Closed junaid1460 closed 4 years ago
I'd say this is a duplicate of #202 (combined with type guards). The cases "url" and "ip address" could also be solved by #6579.
yes, but regex makes it harder to read, also this looks more generic can be applied to any type, regex could be kind of validator within
I mean
const port: number & range(8000, 9000) = 8001
where range could give a curried function that can accept type 'number' which is 8001
This could be just compiler internal implementation for most of the use cases
If we'll drag it into runtime, it will give us ability to create programs with undefined behavior
For example:
const lessThanHalf = (num: number) => num < 0.5
const a: number & (lessThanHalf) = Math.random()
But if we'll check it statically, it will not be possible even to compile this code because the type number
, returned by the random
function, will be not assignable to the type number & (lessThanHalf)
.
So, we can just add predicate to the type of value after checking the value with it.
const lessThanHalf = (num: number) => num < 0.5
const num = Math.random()
if(lessThanHalf(num)) {
// num is `number & (lessThanHalf)` here
} else {
// num is `number` here
}
But I still have a lot of questions: 1) How about functions with different names, but which are doing the same?
const a = (num: number) => true
const b = (num: number) => true
const c = 0
if(a(c)) {
// Should this be valid?
const d: number & (b) = c
}
2) Should predicates be pure? Why?
3) Can we use only named functions or anonymous too?
If yes, how should the type of variable b
look like?
const a = 0
if(((num: number) => true)(a)) {
// What is the type of b?
const b = a
}
If no — don't you think that limiting the checks with named functions only will unnecessarily increase the size of the code?
4) What about generic predicates?
5) How to handle this case?
function a() {
const b = (n: number) => true
return (n: number & (b)) => n
}
const c = a()
The type of c
refers the scope that is not accessible from the scope where c
is declared
IMHO: the approach proposed in this issue adds much more problems than it solves
type inference
, as along as validator b is pure, we can copy it anywhere. Pure also means, no closure.And mainly the validator api should have a design strategy where we decide what's the signature of predicate should be, It should never be any function. Every api needs to have schema and should be predictable.
Everything that has schema should be statically assertable, We define conventions in our codebase that's documented in a cornered file example :
I can't tell from this proposal whether you're proposing that TypeScript evaluate ipAddress
at compile time (which we're not going to do), or if you're proposing that TypeScript insert code into the JS emit to cause ipAddress
to be evaluated at runtime, which we also wouldn't do.
I am proposing that literals can be evaluated at compile time @RyanCavanaugh . Node mostly runs on api side and does lots of query/scripts which can be statically evaluated.
Search Terms
Custom type validators, pure function validators
Suggestion
having a defined way to document shape / value of a generic type like string , number. This could be a static compile time feature or it can be dragged into runtime.
Use Cases
Avoiding mistakes while creating cache keys Validators for URLs in form of string Validators for range
Examples
Checklist
My suggestion meets these guidelines: