将非(null | undefined)类型参数标记为类型错误?

时间:2018-08-02 08:33:31

标签: typescript

是否可以以仅将throwIfMissing标记为编译器错误的方式键入函数test1

function throwIfMissing<T>(x: T): T {
    if (x === null || x === undefined) {
        throw new Error('Throwing because a variable was null or undefined')
    }
    return x;
}

type Foo = string

// should error:
function test1(x: Foo): Foo {
    return throwIfMissing(x);
}

// should NOT error:
function test2(x: Foo | null): Foo {
    return throwIfMissing(x);
}

function test3(x: Foo | undefined): Foo {
    return throwIfMissing(x);
}

function test4(x: Foo | null | undefined): Foo {
    return throwIfMissing(x);
}

“ x / y问题”说明:此功能是将代码库的strictNullChecks标志升级为true的临时拐杖。在我们删除... | null | undefined类型时,我们希望不必要的调用是编译器错误。

我一直在尝试类似conditional types之类的方法,但还没有成功。

1 个答案:

答案 0 :(得分:2)

如果启用了strictNullChecks,则可以使用条件类型来查看传入的T是否包含nullundefined,并且可以使用交集类型来使参数无法(至少不容易)传递给函数

type ErrorIfNotNUllOrUndefined<T, TMessage> = (null extends T ? T : undefined extends T ? T  : TMessage);
function throwIfMissing<T>(x: T & ErrorIfNotNUllOrUndefined<T, "Parameter can't be null don't check">):Exclude<T, null | undefined> {
    if (x === null || x === undefined) {
        throw new Error('Throwing because a variable was null or undefined')
    }
    return x as any;
}

type Foo = string
type dd = (null extends Foo | null ? {} : "Error")
// this is an error 
function test1(x: Foo): Foo {
    return throwIfMissing(x); //Argument of type 'string' is not assignable to parameter of type '"Parameter can't be null don't check"'.
}

// all ok 
function test2(x: Foo | null): Foo {
    return throwIfMissing(x);
}

function test3(x: Foo | undefined): Foo {
    return throwIfMissing(x);
}

function test4(x: Foo | null | undefined): Foo {
    return throwIfMissing(x);
}

如果您没有strictNullChecks,则无法区分stringstring | null | undefined