Skip to content

Instantly share code, notes, and snippets.

@Merott
Last active July 15, 2023 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Merott/c89936400ac56bb92ff4a594b37ec072 to your computer and use it in GitHub Desktop.
Save Merott/c89936400ac56bb92ff4a594b37ec072 to your computer and use it in GitHub Desktop.
A TypeScript guard for object types, with an optional parameter to verify the shape of that object, specifying the properties and their corresponding types.
type BasicTypeMap = {
/* These are the types you might get with the `typeof` operator. */
'string': string,
'number': number,
'bigint': bigint,
'boolean': boolean,
'symbol': symbol,
'undefined': undefined,
'object': object,
'function': (...args: unknown[]) => unknown,
}
type BasicTypeName = keyof BasicTypeMap;
type BasicType<Name extends BasicTypeName> = BasicTypeMap[Name];
export function isObject(value: unknown): value is object
export function isObject<TValue, TProps extends Record<string, BasicTypeName>>(
value: TValue,
props: TProps,
): value is (object extends TValue ? object : TValue) & {
[PropKey in keyof TProps]: BasicType<TProps[PropKey]>
}
export function isObject<TProps extends Record<string, BasicTypeName>>(
value: unknown,
props?: TProps,
) {
if (typeof value !== 'object' || value === null) return false
if (typeof props === 'object') {
for (const propKey in props) {
const propValue = (value as Record<string, unknown>)[propKey]
if (typeof propValue !== props[propKey]) {
return false
}
}
}
return true
}
@Merott
Copy link
Author

Merott commented Jul 15, 2023

Example usage:

export function someFunction(something: unknown) {
  if (isObject(something, { simple: 'boolean' })) {
    something.simple // boolean
  }

  if (
    isObject(something, { a: 'number', complex: 'object' }) &&
    isObject(something.complex, { type: 'string' })
  ) {
    something.a // number
    something.complex // object
    something.complex.type // string
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment