You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Derive boilerplate type guards for unknown types #26078
TypeScript 3 adds an unknown type that must be inspected to be (safely) cast to another type. This manual type-checking code however is just boilerplate; it's easy to get wrong, easy to miss parts, and IMO adds absolutely no value for the programmer to have to type themselves. This boilerplate should be derivable for any non-function type, and several projects exist already that do this (or more); e.g., flow-runtime and io-ts.
This is a limited version of #1573 which suggested blanket runtime type-checking. I am suggesting a builtin operator like as that takes x: unknown as its first argument, a type T as its second, and produces x is T. Call this operator is, maybe.
Also desirable would be for error messages documenting why an unknown value does not validate; e.g. val does not have fields { x: number, y: number }. So the second part of this proposal is for a separate operator is! that is identical to is but throws a TypeError upon a type error.
I think that now that there is an unknown type, where its only use is for users to write mechanically derivable boilerplate to cast it to a known type, this is the logical next step.
I do not believe this is in opposition to the non-goal of adding/relying on runtime type-information. This only adds an extremely limited type reflection mechanism, motivated only by reducing boilerplate.
Use Cases
Any input data that's unknown; e.g. the output of a HTTP endpoint, or a websocket, some user input, JSON.parse, etc.
I think the syntax might be against the design goals of having "just JavaScript" + types. But I guess your proposal could be turned into a quick fix for auto-generating type guards, like this:
typeMessage// hover here to auto-generate a typeguard={type: 'ping',time: number}|{type: 'pong',time: number};// this will get generatedfunctionisMessage(arg: any): arg is Message{return(typeofarg==='object'&&data.arg==='ping'&&typeofdata.arg==='number'||typeofdata==='object'&&data.arg==='pong'&&typeofdata.arg==='number');}// so you can use it with an unknown variable:functiononreceive(data: unknown){if(isMessage(data)){// ...}}
Reacted by Linus Unnebäck, OKUNOKENTARO and Emily Marigold Klassen
As AlCalzone noted, we do not intend to introduce new JS-expression syntax for type-only purposes. that would not be inline with our design goals.
Allowing some narrowing constructs to work on unknown to "prove" some aspects of the type is a valid option though. this is currently tracked by #25720, #10715, #25172, and #21732
Mohamed Hegazy (@mhegazy) TypeScript already has e.g. enums that mechanically generates JavaScript code that is a chore to write manually, but provides immense value. Given how boring and easy-to-mess-up the type-checking code actually is, I think it's at the same level of "tolerable design goal exception". If the problem is just that it's an expression, how about a new statement a la enum:
typeMessage={ ... };typeguardisMessage(arg: unknown): argisMessage;// function isMessage(arg:unknown): arg is Message { ... }
I just don't see what value is provided in having to write this stuff manually. Being able for tooling to generate the boilerplate like AlCalzone suggests would be a decent and probably much less controversial solution.
Reacted by AlCalzone, Maarten Staa, Alex Burner, AndreasGassmann and Shaun Smekel
For anyone finding this issue, this Stack Overflow thread has a few third-party tools that generate runtime checks based on interfaces. I don't know if any of the tools still work.
I also think this would be wonderful to have. This is one of the first problems you have to solve in most applications. TypeScript of course works wonderfully for type checking inside your own system. But in order to validate data coming in to your system you have to resort to using tools that either complicate your build process by adding some additional preprocessing step or using unofficial tools like typescript-is/ttypescript, or complicating the way you define your types such as with io-ts (which many times probably looks odd to many Typescript developers). Maybe the most likely approach is for the "custom transformers" to become more mature in Typescript?
Activity
mikeplus64 commentedon Jul 31, 2018
Related #26064 #7481 #10421
AlCalzone commentedon Jul 31, 2018
I think the syntax might be against the design goals of having "just JavaScript" + types. But I guess your proposal could be turned into a quick fix for auto-generating type guards, like this:
mhegazy commentedon Jul 31, 2018
As AlCalzone noted, we do not intend to introduce new JS-expression syntax for type-only purposes. that would not be inline with our design goals.
Allowing some narrowing constructs to work on
unknownto "prove" some aspects of the type is a valid option though. this is currently tracked by #25720, #10715, #25172, and #21732mikeplus64 commentedon Aug 1, 2018
Mohamed Hegazy (@mhegazy) TypeScript already has e.g. enums that mechanically generates JavaScript code that is a chore to write manually, but provides immense value. Given how boring and easy-to-mess-up the type-checking code actually is, I think it's at the same level of "tolerable design goal exception". If the problem is just that it's an expression, how about a new statement a la
enum:I just don't see what value is provided in having to write this stuff manually. Being able for tooling to generate the boilerplate like AlCalzone suggests would be a decent and probably much less controversial solution.
mattmccutchen commentedon Aug 15, 2018
For anyone finding this issue, this Stack Overflow thread has a few third-party tools that generate runtime checks based on interfaces. I don't know if any of the tools still work.
bensalilijames commentedon Oct 17, 2018
It's worth checking out typescript-is, which is a transformer that implements
is.typescript-bot commentedon Dec 15, 2018
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
sgronblo commentedon Oct 9, 2019
I also think this would be wonderful to have. This is one of the first problems you have to solve in most applications. TypeScript of course works wonderfully for type checking inside your own system. But in order to validate data coming in to your system you have to resort to using tools that either complicate your build process by adding some additional preprocessing step or using unofficial tools like typescript-is/ttypescript, or complicating the way you define your types such as with io-ts (which many times probably looks odd to many Typescript developers). Maybe the most likely approach is for the "custom transformers" to become more mature in Typescript?