typescript - 更窄的类型不能分配给其他类型

标签 typescript typescript-typings typescript-generics

有两种类型:

type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;

在函数代码中

function test1<T>(p: ExcludeStringAndBoolean<T>) {
  let a: ExcludeString<T>;
  a = p;
}

tsc 为行 a = p 抛出错误

Type 'Exclude<T, string | boolean>' is not assignable to type 'Exclude<T, string>'.ts(2322)

但是对于某些用途来说它效果很好:

type CertainType = string | number | boolean;

function test2(p: ExcludeStringAndBoolean<CertainType>) {
  let a: ExcludeString<CertainType>;
  a = p;
}

为什么会这样?

最佳答案

Exclude 是一种条件类型。如果条件类型包含未解析的类型参数(例如 T), typescript 将不会尝试对条件类型进行太多推理。因此可分配性规则变得相当严格。

对于排除,如果第二个参数不同(即测试的类型不同),则可分配性检查失败(例如string | boolean vs string 在你的情况下)。如果第一个参数(即被测试的类型)具有类型关系,则赋值成功。例如,这将起作用:

type ExcludeString<T = any> = Exclude<T, string>;
type ExcludeStringAndBoolean<T = any> = Exclude<T, string | boolean>;

function test1<T extends U, U>(p: ExcludeString<T>) {
  let a: ExcludeString<U>;
  a = p;
}

Playground Link

关于typescript - 更窄的类型不能分配给其他类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59100468/

相关文章:

typescript - 定义 TypeScript 回调类型并提供默认回调值

typescript - 使用 TypeScript 从基类中的静态方法实例化子类

typescript 编译器不显示错误

typescript - 除了可读性之外, `.d.ts` 文件名是否有任何重要意义?

reactjs - react 网格布局与 typescript 不工作

javascript - 设置任意 JavaScript 对象属性的类型

typescript - 传递给通用函数包装器(如 _.debounce)的函数的类型推断

javascript - 表格行折叠?

javascript - 在 tsc TypeScript 编译中包含 CSS 文件

TypeScript 映射类型值取决于键