打字稿:允许通用类型,但不能是其子类型

时间:2020-09-30 09:29:43

标签: typescript generics types typescript-generics

F.e。我想允许任何 object ,但不允许某些子类型的确切实例 下面的代码不会警告我并成功编译。

type Non<N, T> = T extends N ? never : T;

const a: Non<Error, object> = new Error(); // Should get type error

1 个答案:

答案 0 :(得分:2)

您的类型可以起作用,只是不会以您使用它的方式起作用。

使用类型提示const a: Non<Error, object>时,该类型仅被评估一次,并且使用您提供的特定值进行评估:N = ErrorT = object

type Non<Error, object> 
   = object extends Error ? never : object
   = false ? never : object
   = object

换句话说,Non<Error, object>等于object。总是。那是因为这里没有变量,我们只是比较类型object和类型Error

这是一个用法示例,其中您的Non类型有意义,将其用作对type guard function的断言。

const isNotError = <T>(value: T): value is Non<Error, T> => {
    return ! (value instanceof Error)
}

const checkVal = (value: Error | {s: string} ): string => {
    if ( isNotError( value ) ) {
        // value cannot be of type Error
        return value.s;
    } else {
        // value must be of type Error
        return value.message;
    }
}

仅供参考,您在此处编写的内容已经是内置类型ExcludeExclude以与Non类型相反的顺序放置参数,因此您要排除的内容排在第二位。