简体   繁体   English

如何根据 TypeScript 中结构未知的另一个属性的键在界面中键入一个属性?

[英]How to type a property in a interface according to keys of another property has unknown structure in TypeScript?

I used a module can do such thing我用一个模块可以做这样的事情

function print(obj, key) {
  console.log(obj[key])
}

print({'test': 'content'}, '/* vs code will show code recommendation when typing */')

I want to have this feature but I forgot the name of the module and I even don't sure if I misremembered (maybe it's impossible).我想拥有这个功能,但我忘记了模块的名称,我什至不确定我是否记错了(也许不可能)。

I'm working on a package and have a code like this:我正在研究 package 并且有这样的代码:

interface Box {
  content: {
    [key: string]: string
  }
  using: string // key of content 
}

const box: Box = {
  content: {
    'something': 'inside'
  },
  using: 'something'
}

function showBox(box: Box) {
  console.log(box.content[box.using])
}

Actually the content is a object comes from another package using typescript.实际上content是 object 来自另一个使用 typescript 的 package。 I would like not to wrap the type if possible.如果可能,我不想包装类型。

To help devs can find bugs during coding, I'm looking for if there is a way to check invalid Box type like:为了帮助开发人员在编码过程中发现错误,我正在寻找是否有办法检查无效的Box类型,例如:

const box: Box = {
  content: {
    'something': 'inside'
  },
  using: 'samething' // raise error when checking type
}

Or any way can make code recommendation of IDE know the using should be a key of content object.或者任何方式都可以使 IDE 的代码推荐知道using应该是content object 的关键。

My code currently looks like this but it's not what I want, and I don't have any idea to go on我的代码目前看起来像这样,但这不是我想要的,我对 go 没有任何想法

interface Box {
  content: {
    [key: string]: string
  }
  using: keyof Box['content'] // will be string | number
}

Thanks to all response感谢所有回复

Your solution is actually correct, but IDE cannot suggest you anything because keyof Box['content'] is typed to be an arbitrary string.您的解决方案实际上是正确的,但 IDE 无法向您提供任何建议,因为keyof Box['content']被键入为任意字符串。 If you know that content should always have some specific structure, you can just put it inside Box description like this:如果你知道content应该总是有一些特定的结构,你可以把它放在Box description 中,如下所示:

interface Box {
  content: {
    something: string;
  };
  // now it only allowed to be 'something', and IDE will suggest it
  using: keyof Box['content'];
}

If your content 's type is actually a parameter (meaning that you can have boxes for arbitrary types), you should make it a parameter for Box interface, thus making it a generic interface:如果你的content的类型实际上是一个参数(意味着你可以有任意类型的盒子),你应该让它成为Box接口的参数,从而使它成为一个通用接口:

interface GenericBox<T> {
    content: T;
    using: keyof T;
}

Now you can use it like this:现在你可以像这样使用它:

// simple example interface to fill a box
interface TestContent {
    x: string;
    y: number;
}

const genericBox: GenericBox<TestContent> = {
    content: {x: '', y: 0},
    using: 'x', // now it can be only 'x' or 'y', and IDE will suggest it
};

Check it out on the playground .操场上看看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM