【问题标题】:Can I use a template literal containing a variable as an object key?我可以使用包含变量的模板文字作为对象键吗?
【发布时间】:2019-07-16 05:47:52
【问题描述】:

我希望下面的代码可以工作,但不知道为什么不行:

interface Person {
  firstName: string
}

const property: 'Name' = 'Name'

const zack: Person = {
  [`first${property}`]: 'Zack'
}

创建zack 会引发错误:

Property 'firstName' is missing in type '{ [x: string]: string; }' but required in type 'Person'.

更多地玩这个,任何字符串连接似乎都是问题:

type EqualsFirstName = 'firstName'

const value: EqualsFirstName = 'first' + 'Name'

这也不行。

【问题讨论】:

标签: typescript template-literals


【解决方案1】:

TypeScript 编译器在评估映射类型时相当严格。有很多事情不能很好地与他们一起工作,这就是其中之一。它在您断言类型时起作用:

const zack: Person = {
    [`first${property}` as 'firstName']: 'Zack'
}

虽然如下代码所示,这并没有真正的帮助,它也可以正常编译,但在运行时会失败:

const property: 'Foo' = 'Foo'

const zack: Person = {
  [`first${property}` as 'firstName']: 'Zack'
}

另一个(有点笨拙)的选项是用as 断言Person 类型(并首先对unknown 进行断言):

const zack = {
  [`first${property}`]: 'Zack'
} as unknown as Person

与第一个选项一样,如果断言无效,这在运行时对您没有帮助。

我建议您尝试不使用此符号并选择更“TS 编译器友好”的方式。这是一个非常不寻常的结构,在技术上是有效的,但在实践中你宁愿避免。

【讨论】:

【解决方案2】:

这个技巧可能会奏效

interface Person {
  firstName: string
}

const property: 'Name' = 'Name'
type EqualsFirstName = 'firstName'

const zack: Person = {
  [`first${property}` as EqualsFirstName]: 'Zack'
}

【讨论】:

    猜你喜欢
    • 2019-02-02
    • 1970-01-01
    • 2020-07-31
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多