在 TypeScript 接口中描述属性对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42847862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:37:37  来源:igfitidea点击:

Describe property object in TypeScript interface

typescripttypestype-conversionwebstormtypescript2.0

提问by Alendorff

I want to describe some interface with nested objects. How can I do it without creation of Interfaces for nested objects?

我想用嵌套对象描述一些接口。如果不为嵌套对象创建接口,我该怎么做?

interface ISome {
  strProp:string;
  complexProp:{
    someStrKeyWhichIsDynamic:{
      value:string;
      optValue?:string;
    }
  };
}

I also tried (UPD: it's okay actually)

我也试过(UPD:其实没问题

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

But I cant to assign an object like

但我不能分配一个对象

let dynamicStrKey = 'myKey';
  {
   strProp:'str', 
   complexProp:{
     [dynamicStrKey]:{
       value:'something here',
       optValue: 'ok, that too',
    }
  };

to variable with ISometype without type assertion <ISome>. At least WebStorm highlights this assignment as an error.

具有ISome类型的变量,没有类型断言<ISome>。至少 WebStorm 将此分配突出显示为错误。

How to properly describe nested objects?

如何正确描述嵌套对象?

采纳答案by Alendorff

Finally, I think that my second variant was correct

最后,我认为我的第二个变体是正确的

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

For dynamic key you can just write [dynamic:string]to specify that here will be some string property. Seems like I had webstorm error which wasn't related to the issue.

对于动态键,您可以只写[dynamic:string]来指定这里将是一些字符串属性。似乎我遇到了与问题无关的 webstorm 错误。

BTW, if you have some string based enum, you may want to use [key in MyEnum]: {...}instead of [key:string]. That solves error:

顺便说一句,如果你有一些基于字符串枚举,您可能要使用[key in MyEnum]: {...}替代[key:string]。这解决了错误:

TS1337 an index signature parameter type can not be a union type.

TS1337 索引签名参数类型不能是联合类型。

And if you have a literal object, e.g. const obj = { prop1: 'blah', prop2: 'blahblah' }

如果你有一个文字对象,例如 const obj = { prop1: 'blah', prop2: 'blahblah' }

You may want to use [key in keyof typeof obj]: {...}to describe that your dynamic key can be only 'prop1' or 'prop2' (or, more generic, value from Object.keys(obj) )

您可能想要使用[key in keyof typeof obj]: {...}来描述您的动态键只能是 'prop1' 或 'prop2' (或者,更通用的值来自Object.keys(obj))

回答by Alendorff

There is nothing wrong with your first two examples. They both compile fine, and mean what they say.

您的前两个示例没有任何问题。他们都编译得很好,并且是他们所说的。

In your third example, you apparently want the property name to be "dynamic". But remember, TS operates at compile time. At compile time, dynamicStrKeyhas no value yet. Therefore, it is meaningless to try to use it as a property name in a type definition. You cannot define a compile-time artifact using a run-time value.

在您的第三个示例中,您显然希望属性名称为“动态”。但请记住,TS 在编译时运行。在编译时,dynamicStrKey还没有价值。因此,尝试将其用作类型定义中的属性名称是没有意义的。您不能使用运行时值定义编译时工件。

回答by holi-java

the code of the second part is support dynamic properties.you can't use with the last one,because type not emit to the javascript code.I think you just like something below,using generic instead.for more details,you can see typescript index types.

第二部分的代码支持动态属性。你不能和最后一个一起使用,因为类型不会发送到javascript代码。我想你只是喜欢下面的东西,使用泛型代替。更多细节,你可以看打字稿索引类型

interface ISome<K extends string> {
    strProp: string;
    complexProp: {
        [P in K]: {
            value: string;
            optValue?: string;
        }
    };
}


let foo: ISome<"foo"> = {
    strProp:"foo",
    complexProp:{
        foo:{
            value:"foo"
        }
    }
};

let bar: ISome<"bar"> = {
    strProp:"bar",
    complexProp:{
        bar:{
            value:"bar",
            optValue:"<optional>"
        }
    }
};

let foobar: ISome<"foo"|"bar"> = {
    strProp:"foo",
    complexProp:{
        foo:{
            value:"foo"
        },
        bar:{
            value:"bar",
            optValue:"<optional>"
        }
    }
};

// interesting things that use with any|never types
let anything:ISome<any|never>={
    strProp:"foo",
    complexProp:{}
};