1
votes

With tsconfig.json strict: true, I have the following types

type Nullable<T> = T | null | undefined

then, I have a function which accept nullable data and return a nullable data with different type, for example:

const transformA: (a: Nullable<A1>) => Nullable<A2>

It works well. But then when consuming the transformA, it always returns Nullable which makes the downstream nullable.

If I already ensure the input of transformA is not Nullable, I want the return of transformA to be not nullable too.

const transformA: (a: A1) => A2

Declare 2 functions for that purpose I think it is too much as I have a ton of transformation functions like that. So I want to use overload function

function transformA(a: A1): A2;
function transformA(a: Nullable<A1>): Nullable<A2>;

function transformA(a: A1 | Nullable<A1>): A2 | Nullable<A2> {...}

IMO, this is not very concise and good-looking. I thinking about:

const transformA: <A1, A2>(a: MayBeNullable<A1>): NullableIfInputNullable<A2>

or something similar.

My wish are:

const a1: Nullable<A1>
const ret1 = transformA(a1) // ret1 can infer to Nullable<A2>

const a2: A1

const ret2 = transformA(a2) // ret2 infer to A2, not Nullable<A2>

is it feasible? Any feedback are welcome

1
You can make the function generic and use a conditional type in the return type, but I don't necessarily think it'll be shorter - Titian Cernicova-Dragomir
Looks good enough for me, it's absolutely shorter than mine, the other is just a naming issue. Thank you! I tried almost the same as what you gave, but still, you point me to the last important piece. - Kay Nguyen
added as an answer - Titian Cernicova-Dragomir

1 Answers

0
votes

You can make the function generic, and make the return type a conditional type that you can reuse in multiple places:

type Nullable<T> = T | null | undefined
type NullIfInputIsNull<C, T> = C extends null | undefined ? null | undefined : T

function transformA<T extends Nullable<A1>>(a: T): NullIfInputIsNull<T, A2> {
  return a as any;
}

Playground Link