Repository navigation
Description
TypeScript Version: 2.1.1
Also relates to #12424
I recently spent some time looking at the discussion on a safe navigation ?. operator in typescript/javascript (see #16, and https://esdiscuss.org/topic/existential-operator-null-propagation-operator). Then it struck me that ES6 proxies could be a solution that didn't require new language operators. Wrote something working together, and also found this existing npm package: https://www.npmjs.com/package/safe-proxy. In summary, you'd be able to write
// Safe (only does actual property access if underlying object is valid)
safe(a).b.c().d[0]
// ...instead of the functionally equivalent but unsafe
a.b.c().d[0]Now, how do I type annotate this? At first, I thought maybe the new mapped types in Typescript 2.1 could be used, but then I've come to believe that it isn't possible currently (please let me know how to do this otherwise). What I miss is a generalized way of narrowing optional types under ---strictNullChecks.
For example, let's consider using the mapObject from the the Typescript 2.1 release wiki writeup, with optional properties:
const names:{ foo: string, bar?: string} = { foo: "" };
mapObject(names, s => s.length)This results in a TS2345 error (basically bar can't be optional)
Now, back to the SafeProxy type. The best I can come up with today is
type SafeProxy<T> = {
[P in keyof T]: SafeProxy<T[P]&any>;
};...which is marginally better than just any.
I would want (and need for my example above) to define something like below. NOTE: the assertion operator here is made-up-syntax. I suggested an exclamation mark after the actual type, but this could obviously be debated.
type SafeProxy<T> = {
[P in keyof T]: SafeProxy<T[P]!>;
};Interestingly it would kind of enable the reverse of Partial<T>:
// existing in lib.d.ts
type Partial<T> = {
[P in keyof T]?: T[P];
};
// potential
type Complete<T> = {
[P in keyof T]: T[P]!;
}Side note: As I intend the SafeProxy class to implement Symbol.toPrimitive, no trailing __value or similar would be needed. This seems to play well with typescript primitives though
Some other usages (that I guess all play pretty well with --strictNullChecks)
- advanced assertion style functions
- default mechanism functions
Activity
zpdDG4gta8XKpMCd commentedon Jan 2, 2017
this requires subtraction types #4183
mhegazy commentedon Jan 5, 2017
Not sure i see why this requires subtraction types..
mhegazy commentedon Jan 5, 2017
If
safewas one level only proxy, you should be able to use generic type inference to get the non-optional version of your type. You can achive this by typesafeas:you could even add support for
null:with #12596 implemented, you can even allow dotting off unknown properties if you add a string indexer to the output:
for the recursive version of it, #12769 tracks fixing it.
In general
!type operator is useful, but you can use generic type inference to get the same scenario achieved.staeke commentedon Jan 6, 2017
Thanks Mohamed Hegazy (@mhegazy) for a great reply. I realize that it's a truly useful and powerful concept to stop thinking of type parameters as "the input type", and more like "the common denominator between inputs/outputs". Reminds me of Type used in Angular to denote the "type of the constructor". Maybe worth adding something similar to the documentation around Partial?
masaeedu commentedon Apr 5, 2017
Mohamed Hegazy (@mhegazy) Can this be done without declaring and implementing a function? If I have a partial type
T, how do I simply declare a variable of the "un-partialed" type?mhegazy commentedon Mar 2, 2018
This should be doable now with
NonNullabletype.