Is it possible de create a genric assert type function for object.
Something like this :
assertIsTypeOf<ExpectedType extends object>(obj: unknown): obj is ExpectedType {
return Object.keys(obj).every((key) => key in (keyof ExpectedType));
}
Do you have an idea how to do something like that ? Or a better way ?
CodePudding user response:
Indeed, functions with type predicates can be generic. But since types are erased during compilation, you can not use types at runtime to do any kind of validation. So you have to supply additional arguments to do the validation at runtime.
You could possibly send another object containing all the properties you want to check.
function assertIsTypeOf<T extends object>(obj: unknown, expectedType: T): obj is T {
return !!obj && Object.keys(expectedType).every((key) => key in obj);
}
console.log(assertIsTypeOf({ a: "123" }, { a: "" }))
console.log(assertIsTypeOf({}, { a: "" }))
Based on your implementation it does not look like you are actually checking the type of the properties. You only check if they exist. So you could also just pass an array of property names.
function assertIsTypeOf<T extends string>(
obj: unknown,
expectedProps: T[]
): obj is Record<T, unknown> {
return !!obj && expectedProps.every((key) => key in obj);
}
console.log(assertIsTypeOf({ a: "123" }, ["a"]))
console.log(assertIsTypeOf({}, ["a"]))