如何动态引用 TypeScript 接口属性的值?

huangapple go评论132阅读模式
英文:

How to dynamically refer to TypeScript interface property's value?

问题

请看这个愚蠢的例子:

interface Building {
  rooms: number
  kitchen: {
    hasOven: true
  }
  bathroom: {
    numberOfSinks: number
  }
}

interface Select<T> {
  name: keyof T
  fields: (keyof T[this.name])[] // <-- 这不是有效的代码。我应该怎么做?
}

const x: Select<Building> = {
  name: 'kitchen',
  fields: ['hasOven'] // 因为我指定了 'kitchen',所以它只允许 'hasOven'
}

const y: Select<Building> = {
  name: 'bathroom',
  fields: ['numberOfSinks'] // 因为我指定了 'bathroom',所以它只允许 'numberOfSinks'
}

上面的代码不起作用。

如何使 Select<T> 接口能够动态引用 name 属性的值,并使用它来确定可用的键值?

非常感谢!

英文:

Consider this silly example:

interface Building {
  rooms: number
  kitchen: {
    hasOven: true
  }
  bathroom: {
    numberOfSinks: number
  }
}

interface Select<T> {
  name: keyof T
  fields: (keyof T[this.name])[] // <-- This is not valid code. What should I do instead?
}

const x: Select<Building> = {
  name: 'kitchen',
  fields: ['hasOven'] // Because I specified 'kitchen', it only allows 'hasOven'
}

const y: Select<Building> = {
  name: 'bathroom',
  fields: ['numberOfSinks'] // Because I specified 'bathroom', it only allows 'numberOfSinks'
}

The above code does not work.

How do I make the Select<T> interface to be able to refer to the name property's value dynamically and use that to determine the available key values?

Thanks so much in advance!

答案1

得分: 2

以下是代码的翻译部分:

无法在不引入第二个泛型类型的情况下完成:

interface Select<T, K extends keyof T> {
    name: K
    fields: (keyof T[K])[]
}

所以现在

const a: Select<Building, "bathroom"> = {
    name: 'bathroom',
    fields: ['hasOven'] // 不行!
}

const b: Select<Building, "steering-wheel"> = { // 不行!
    name: 'steering-wheel',
    fields: ['hasOven'] // 不行!
}

const c: Select<Building, "bathroom"> = {
    name: 'steering-wheel', // 不行!
    fields: ['numberOfSinks']
}

Playground链接

英文:

Can't be done without introducing a second generic type:

interface Select&lt;T, K extends keyof T&gt; {
    name: K
    fields: (keyof T[K])[]
}

so now

const a: Select&lt;Building, &quot;bathroom&quot;&gt; = {
    name: &#39;bathroom&#39;,
    fields: [&#39;hasOven&#39;] // NO!
}

const b: Select&lt;Building, &quot;steering-wheel&quot;&gt; = { // NO!
    name: &#39;steering-wheel&#39;,
    fields: [&#39;hasOven&#39;] // NO!
}

const c: Select&lt;Building, &quot;bathroom&quot;&gt; = {
    name: &#39;steering-wheel&#39;, // NO!
    fields: [&#39;numberOfSinks&#39;]
}

Playground Link

huangapple
  • 本文由 发表于 2023年3月10日 02:01:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75688417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定