The "Assert signatures" feature looks excellent. The biggest issue with typescript has always been validating external inputs actually meet the type contracts that your code says they do. With this, it looks like this could be written as library!
How do you verify it now? I've been using typeguards, but since i haven't found a good way to generate interfaces from typeguard functions or typeguard functions from interfaces I have to do each manually:
interface ContactInfo {
address_1: string;
address_2?: string;
city: string;
state: string;
zip: string;
phone: number;
}
function isContactInfo(arg: any): arg is ContactInfo {
let valid = false;
const contactInfoFields: { readonly [key: string]: string[] } = {
address_1: [ 'string', ],
address_2: [ 'string', 'undefined' ],
city: [ 'string', ],
state: [ 'string', ],
zip: [ 'string', ],
phone: [ 'number' ],
};
if (typeof arg !== 'object') {
return valid;
}
for (const key in contactInfoFields) {
if(!contactInfoFields[key].includes(typeof arg[key]) || arg[key] === '' || Number.isNaN(arg[key])) {
return valid;
}
}
valid = true;
return valid;
}
- io-ts[1]
This requires you to write your types as a runtime value, and allows you to extract static types from those, e.g.:
const ContactInfo = t.type({
address_1: t.string,
...
})
type ContactInfo = t.TypeOf
You can validate objects with `ContactInfo.decode(someObject)`Note that we can have the same name for the type and value because they live in different namespaces. When you do ContactInfo.decode, you're calling the decode property of `const ContactInfo`. When you use `ContactInfo` in a type position (e.g. `function x(arg: ContactInfo)`), you're using the `type ContactInfo` declaration
- typescript-is[2]
This uses TypeScript's transformer API. You can use it with https://github.com/cevek/ttypescript. It generates validators for your interfaces/types/etc at compile-time.