【问题标题】:Describe property object in TypeScript interface在 TypeScript 接口中描述属性对象
【发布时间】:2017-08-08 10:35:04
【问题描述】:

我想描述一些嵌套对象的接口。在不为嵌套对象创建接口的情况下如何做到这一点?

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

我也试过了(UPD:其实没关系

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

但我不能分配像这样的对象

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

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

如何正确描述嵌套对象?

【问题讨论】:

    标签: typescript types type-conversion webstorm typescript2.0


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      你的前两个例子没有错。他们都编译得很好,并且是他们所说的。

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

      【讨论】:

      • 但是如果我想拥有动态属性,我应该如何描述呢?我想指定这里将是一些属性,它应该是一个字符串,它应该有一些对象值,这也是描述的。
      • 正如我所说,如果我正确理解了您的问题,您无法定义编译时 TS 类型,其属性的值直到运行时才知道。
      【解决方案3】:

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

      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:{}
      };
      

      【讨论】:

        猜你喜欢
        • 2019-04-06
        • 2019-09-27
        • 1970-01-01
        • 2016-03-24
        • 1970-01-01
        • 1970-01-01
        • 2018-11-19
        • 2020-09-03
        • 2016-02-26
        相关资源
        最近更新 更多