-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Derive boilerplate type guards for unknown
types
#26078
Comments
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: type Message // hover here to auto-generate a typeguard
= { type: 'ping', time: number }
| { type: 'pong', time: number };
// this will get generated
function isMessage(arg: any): arg is Message {
return (typeof arg === 'object' && data.arg === 'ping' && typeof data.arg === 'number' ||
typeof data === 'object' && data.arg === 'pong' && typeof data.arg === 'number');
}
// so you can use it with an unknown variable:
function onreceive(data: unknown) {
if (isMessage(data)) {
// ...
}
} |
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 |
@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 type Message = { ... };
typeguard isMessage(arg: unknown): arg is Message;
// 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. |
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. |
It's worth checking out typescript-is, which is a transformer that implements |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
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? |
Search Terms
validate
reflect
assert
unknown
Suggestion
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
andio-ts
.This is a limited version of #1573 which suggested blanket runtime type-checking. I am suggesting a builtin operator like
as
that takesx: unknown
as its first argument, a typeT
as its second, and producesx is T
. Call this operatoris
, 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 operatoris!
that is identical tois
but throws aTypeError
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.Examples
should, roughly, generate
The text was updated successfully, but these errors were encountered: