-
Notifications
You must be signed in to change notification settings - Fork 13k
Description
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
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.
Examples
type Message
= { type: 'ping', time: number }
| { type: 'pong', time: number };
function onreceive(data: unknown) {
if (data is Message) {
...
}
}
should, roughly, generate
function onreceive(data) {
if (typeof data === 'object' && data.type === 'ping' && typeof data.time === 'number' ||
typeof data === 'object' && data.type === 'pong' && typeof data.time === 'number') {
...
}
}