【问题标题】:Adding type to a literal in TypeScript在 TypeScript 中为文字添加类型
【发布时间】:2021-08-03 18:09:29
【问题描述】:

我可以在 TypeScript 中为文字添加类型吗?类似于以下内容:

type State = 'DRAFT' | 'PUBLISHED';
(['DRAFT', 'OOPS']: State[]).map(s => doSomethingWithState(s)); // Should be flagged by the compiler as 'OOPS' is not compatible with State
(['DRAFT']: State[]).map(s => doSomethingWithState(s)); // Valid
(['DRAFT', 'PUBLISHED']: State[]).map(s => doSomethingWithState(s)); // Valid

我尝试过使用as,但这告诉编译器将其视为给定类型,而不是检查文字是否属于给定类型。

我也可以const foo: Type = ...,但我不需要分配这个值,我只想声明它并立即使用它。

【问题讨论】:

  • 您想要实现的目标有点混乱。但是如果你想将OOPS 添加到State。你必须在第一行。动态添加到联合类型是可能的......但是您必须在创建类型之前让数组包含您想要的数组中的每个字符串文字。看到这个:stackoverflow.com/a/55505556/298455
  • 'OOPS' 不是工会的一部分;这是故意的吗?
  • 要么将OOPS 放入State,要么使用包含它的新State 扩展type(例如,如果State 来自供应商,但您的 代码需要使用新类型 - 警告:您不能将该值传递给供应商的类型)。
  • 我已经更新了示例。我认为“OOPS”这个名字会很明显这是一个故意的错误来证明这个问题,但我想不是......
  • 你的意思是像this这样的东西吗?

标签: typescript


【解决方案1】:

我认为问题在于 TypeScript 无法在编译时确定具有“更通用”类型的数组,例如 string[] 是否仅包含来自受限类型(如 State)的元素。这样的检查只能在运行时进行(常量数组除外,这就是为什么使用const 时它可以工作),这就是为什么从string[]State[] 的转换总是有效的原因。例如:

type State = 'DRAFT' | 'PUBLISHED';

let a = ['DRAFT', 'DRAFT', 'PUBLISHED'];
let b: State[] = a;

分配给b 将导致Type 'string[]' is not assignable to type 'State[]' 错误。您可以使用强制转换为State[] 来解决问题,但是:

let a = ['DRAFT', 'OOOPS', 'PUBLISHED'];
let b: State[] = a as State[];

赋值不会触发错误:编译器很乐意强制转换 a 忽略其内容,因为它不知道其内容。

因此,您的问题的答案是:可能无法完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-06
    • 2017-03-26
    • 2020-12-06
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2017-11-14
    相关资源
    最近更新 更多