在TypeScript接口中描述属性对象

时间:2017-03-17 01:50:24

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

我想用嵌套对象描述一些接口。如果没有嵌套对象的创建接口,我怎么能这样做?

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将此分配突出显示为错误。

如何正确描述嵌套对象?

3 个答案:

答案 0 :(得分:3)

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

在您的第三个示例中,您显然希望属性名称为&#34; dynamic&#34;。但请记住,TS在编译时运行。在编译时,dynamicStrKey尚无价值。因此,尝试将其用作类型定义中的属性名称是没有意义的。您无法使用运行时值定义编译时工件。

答案 1 :(得分:2)

第二部分的代码是支持动态属性。你不能使用最后一个,因为类型没有发出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:{}
};

答案 2 :(得分:1)

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

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

对于动态密钥,您只需编写[dynamic:string]来指定这里将是一些字符串属性。好像我遇到了与此问题无关的网络风暴错误。

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

  

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

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

您可能希望使用[key in keyof typeof obj]: {...}来描述您的动态密钥只能是&#39; prop1&#39;或者&#39; prop2&#39; (或更通用的,来自Object.keys(obj的值))