【问题标题】:More narrow type is not assignable to other更窄的类型不能分配给其他
【发布时间】:2020-03-24 19:06:35
【问题描述】:

有两种:

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;
}

为什么会这样?

【问题讨论】:

  • 有趣的案例。出于好奇将代码复制到 TS playground:link

标签: typescript typescript-typings typescript-generics


【解决方案1】:

Exclude 是一个条件类型。如果条件类型包含未解析的类型参数(例如T),打字稿将不会尝试对条件类型进行太多推理。所以可分配性规则变得非常严格。

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

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 网站上存在文档页面的链接,您能否补充您的答案?
  • @AndreiKovalev 我希望我能。大多数真正神秘的东西都只在 GH 上,并不容易找到。我在这里遇到的条件类型兼容性github.com/microsoft/TypeScript/issues/… 评论者提到他是从编译器代码评论中得到的......所以我猜是官方的? ?
猜你喜欢
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
  • 2022-01-27
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
相关资源
最近更新 更多