TypeScript Version: 2.2.1
Code
interface Foo {
bar: {
baz: number;
} | null;
}
type Baz = Foo["bar"]["baz"]; // This doesn't compile with the error: "Property 'baz' does not exist on type '{ baz: number; } | null'."
let x: Baz = 0;
Expected behavior:
I would expect there to be a way to specify bar is non-null, such as Foo["bar!"].
Actual behavior:
The code doesn't compile with the following error message:
"Property 'baz' does not exist on type '{ baz: number; } | null'."
This requires a null assertion type operator, as you noted. something of the form type Baz = (Foo["bar"])!["baz"];.
Also referenced in https://github.com/Microsoft/TypeScript/issues/13253
Another dupe: #17370
As it seems a special operator for this is no longer planned (see https://github.com/Microsoft/TypeScript/pull/17948#issuecomment-327859311), I added an example for this at https://github.com/Microsoft/TypeScript/pull/17961/commits/4d14c9fb1da5cf6f5db024e8b25c87336d834103 now.
@tycho01 This still possible somehow? Apparently the syntax used in your example is no longer valid.
I'm trying to achieve the opposite of Partial<T> to describe initialized (i.e defaults applied) to option objects (a mix of optional and required properties).
The following would be possible if ! operator or Assert<T> were available:
/**
* Make all properties in T required
*/
type Whole<T> = {
[P in keyof T]!: T[P];
};
Is there any alternatives?
@cvsguimaraes: it's an outstanding PR, it has never been possible yet on master. The current topic is just a sub-case of #4183.
It's not perfect, but a workaround for the example at the top is to do
type Baz = (Foo["bar"] & {"baz": {}})["baz"];
to get the deeper type. it does make the type number & {} but it at least makes the above code work
To simplify that, i made the following helper (called Get because of _.get):
type Getter<T, K extends string> = T & Record<K, {}>;
type Get<T, K extends keyof Getter<T, K>> = Getter<T, K>[K];
// Usage:
type Baz = Get<Foo["bar"], "baz">;
Fixed in https://github.com/Microsoft/TypeScript/pull/22094 by tweaking the compiler to allow partial unions for indexed types - therefore not requiring a null assertion operator.
a NonNullable type was part of #21847
Discussed this again in #22445. Conclusion, with NonNullable available now with conditional types, the original scenario should be unblocked, no reason to add new rules.