网站搜索

typescript - `never` 目前不能赋值但被接受为泛型类型?


我想知道为什么 never 类型可以作为泛型扩展类型的输入。

例如:

type Pluralize <A extends string> = `${A}s`

type Working = Pluralize <'language'>   // 'languages' -> Work as expected
type WhyIsItWorking = Pluralize <never> // never       -> Resolves and don't complain

操场

有人知道一个全面的答案,或者有关于 never 类型的好的教程吗?
根据我在官方文档中看到的,never 永远不可赋值...

最后,如果我希望 ts 编译器在输入无效时发出警告,应该使用什么正确的模式?

答案#1

never 扩展 everything。要理解原因,将类型视为集合可能会有所帮助。

考虑代码 A extends string。如果我们用集合的角度来思考,这意味着“A 是 string 的一个子集”。string 是所有可能字符串的集合(所以 "a"、"aa"、"aaa" 等等都在其中)。像 "a" | "b" 这样的类型是从 string 继承的,因为包含 "a" 和 "b" 元素的集合是所有可能字符串集合的子集。像 "a" | 2 这样的类型不是从 string 继承的,因为它有一个 2 元素,而 string 中没有这个元素,因此它不是 string 的子集。

那么 never 是什么集合呢?它是空集。集合中没有任何值。这就是为什么无法将值赋给 never,因为不存在适合它的值。但是因为它是空集,根据定义,它是每个其他集合的子集。因此,它可以从所有类型扩展。

最后,如果我希望 TypeScript 编译器在输入无效时发出警告,应该使用什么正确的模式?

你将无法从此类型中禁止 never,但我不确定你为什么需要这样做。虽然类型 Pluralize<never> 是合法的,但不可能构造出匹配该类型的东西。例如,如果我有一个像这样的函数:

function test<T extends string>(val: Pluralize<T>) {
  // ... 
}

... 并且试图调用 test<never>(/* 在此处插入参数 */),没有任何参数我可以放入我的函数调用中是 TypeScript 会允许的。