【发布时间】:2019-10-04 17:13:02
【问题描述】:
我有一个无法修改的大型复杂接口 X,我想根据接口 X 中的属性和子属性定义一些较小的类型,我想将其用作函数参数的类型。我还想避免单独重新声明 X 中已有的内容。
interface X {
a:number;
c:{
aa:number;
cc:{
aaa:string;
}
},
d?:{
aa:number;
cc:{
aaa:string;
}
},
e:{
aa:number;
cc:{
aaa:string;
}
}[]
}
我知道我可以使用映射类型来访问子类型[编辑注释:子类型是错误的术语,这应该称为嵌套级别类型,请参阅下面的答案] 这应该是对象,例如:
type C = X["c"]; // { aa:number; cc:{ aaa:string } }
type C_CC = X["c"]["cc"]; // { aaa: string }
type D = X["d"]; // { aa:number; cc:{ aaa:string } } | undefined
但是,当属性可能未定义时,事情变得有点棘手。如果我想获得 X.d.cc 的类型...(应该给出 {aaa:string} )我该怎么做?还是有可能?
以下两次尝试都报错:
type D_CC1 = X["d"]["cc"]; // error? Due to the (d?) possibly undefined?
type D_CC2 = Required<X["d"]>["cc"]; // error also?
另外,当涉及到数组时,我也有点困惑,例如上面的 E:
type E = X["e"]; // { aa:number; cc:{ aaa:string } }[]
type E_CC1 = X["e"]["cc"]; // error
type E_CC2 = X["e"][0]["cc"]; // got the result I wanted: { aaa: string }
第三行似乎有效,但我不确定使用 [0] 的逻辑是什么——看起来很老套。我想知道这是否是正确的方法。
编辑:将类型名称从 D_CC 更改为 D_CC1 和 D_CC2 以避免歧义。
【问题讨论】:
-
我对 D_CC 没有任何错误。你确定你只是没有同时声明两者都使用相同的名称,因此是重复的标识符吗?
-
我在 ["cc"] 下得到 typescript 波浪线并出现错误:类型 '{ aa: number; 上不存在属性 'cc'抄送:{aaa:字符串; }; } | undefined'.ts(2339). 但是输入
type D_CC3 = Required<X>["d"]["cc"];有效!但这是做事的正确方式吗(使用Required)?
标签: typescript