i'm trying to validate data that my application receives. a short example is the following:
function getField(data:unknown):string {
if (typeof data !== 'object') {
throw new Error('e1');
}
if (data == null) {
throw new Error('e2');
}
const { field } = data;
if (typeof field !== 'string') {
throw new Error('e3');
}
return field;
}
i need to extract a string-field from the data. the code should throw if the shape of the data is invalid. the problem is, the above code does not typecheck. it fails with "Property 'field' does not exist on type '{}'.". i know i can add some any
and it will work, but i'm trying to do this without any
, in a type-safe way.
There is a suggestion to allow the in
type guard to asset the existence of properties but it is not implemented (GH)
You can use a type assertion which should be safe enough (const { field } = data as { field: unknown };
) or you can use a custom type guard to check for the existence of the property:
function hasProp<K extends PropertyKey>(data: object, prop: K): data is Record<K, unknown> {
return prop in data;
}
function getField(data: unknown): string {
if (typeof data !== 'object') {
throw new Error('e1');
}
if (data == null) {
throw new Error('e2');
}
if (!hasProp(data, 'field')) {
throw new Error('field does not exist');
}
const { field } = data;
if (typeof field !== 'string') {
throw new Error('e3');
}
return field;
}
Playground Link
Note Since you are throwing exceptions, you might use the new assertion syntax: Playground Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With