Home > Blockchain >  Inline evaluation different from non-inline
Inline evaluation different from non-inline

Time:09-08

What makes compiler return different results for these two mapped types:

type NonNullableObj1<O> = {[Key in keyof O] : O[Key] extends null ? never : O[Key]}

type NotNull<T> = T extends null  ? never : T;
type NonNullableObj2<T> = {[P in keyof T]: NotNull<T[P]>}

type Nullable = {prop: string | null};

type ResultOf1 = NonNullableObj1<Nullable>; // { prop: string | null }
type ResultOf2 = NonNullableObj2<Nullable>; // { prop: string }

Playground

CodePudding user response:

Both types return different results because of distributive conditional types.

In NotNull, T is a naked generic type on the left side of a condtional. If a union is passed for T, each member of this union will be distributed over the conditional. So string and null will be evaluated seperately. Only string does not extend null, so the type evaluates to just string.

In NonNullableObj1, O[Key] is not a naked generic type because of the indexed access. Therefore, no distribution takes place and the whole union string | null is evaluated in the conditional at once. Since string | null does not extend null, it resolves in the false-branch to O[Key] which is string | null.

  • Related