[DRAFT/RFC] `Uncertain` type
See original GitHub issueSuggestion
đ Search Terms
uncertain typecheck runtime
â Viability Checklist
My suggestion meets these guidelines:
- This wouldnât be a breaking change in existing TypeScript/JavaScript code
- This wouldnât change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isnât a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScriptâs Design Goals.
â Suggestion
Add uncertain
type to notify there is a chance the input wonât be exactly the type as you wish.
đ Motivating Example
Hereâs an example:
// in ts code, this is normal and well
export function foobar(x: number) {
return x % 2 ? "foo" : "bar"
}
// in js code, however
foobar("2")
// but the error message does not help
Hereâs how you could solve it:
// in ts code, this is normal and well, Uncertain accepts any type except unknown, undefined and null
export function foobar(x: Uncertain<number>) {
if (!Number.isInteger(x)) {
throw "x is not a number"
} else { // x must be a number (and an integer)
return x % 2 ? "foo" : "bar"
}
}
// in js code, now we will get a better error message
foobar("2")
However, if you have multiple other checks, they might fail as well. Thus, even after strong runtime assertion, we still consider the uncertain variable to still be uncertain:
// in ts code, this is normal and well
export function foobar(x: Uncertain<number>) {
if (!Number.isInteger(x)) {
throw "x is not a number"
}
// Error: x is uncertain
return x % 2 ? "foo" : "bar"
}
// in js code, now we will get a better error message
foobar("2")
For this situation, you use !
postfix operator to assert certainty:
// in ts code, this is normal and well
export function foobar(x: Uncertain<number>) {
if (!Number.isInteger(x)) {
throw "x is not a number"
}
// force x to be one of the type in Uncertain<number> which is number
return x! % 2 ? "foo" : "bar"
}
// in js code, now we will get a better error message
foobar("2")
đť Use Cases
Itâs very simple: sometime you arenât so sure whether your input really is the right type in runtime, especially for JS to TS interop. Sometimes due to lack of information you might have entered a string equivalent of the number while TS âexpectsâ number. This would of course fail, but the error message could be cryptic, and also we should be able to take care of this bad expected type situation by hand preemptively.
Prior Art
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:11 (9 by maintainers)
Top GitHub Comments
Maybe a better alternative is to allow a function to define whether it could throw, and if so, what type of errors:
Could it be a declaration emit feature? For example, all
Uncertain<T>
gets re-written toT
in the emitted declaration, but during compilation, itâs treated asunknown
.