请参见下面的代码段
interface MyObj {
myOptionalProp: MyOptionalPropObj; // NOT OPTIONAL
}
interface MyOptionalPropObj {
myProp1: SomeType;
myProp2?: SomeType;
}
type Test1 = MyObj['myOptionalProp']['myProp1']; // Works
type Test2 = MyObj['myOptionalProp']['myProp2']; // Works
如果MyObj
不是可选的,则访问Test1
中要分配给Test2
和myOptionalProp
的嵌套属性会很好。
但是。一旦myOptionalProp
是可选的:
interface MyObj {
myOptionalProp?: MyOptionalPropObj; // OPTIONAL
}
interface MyOptionalPropObj {
myProp1: SomeType;
myProp2?: SomeType;
}
type Test1 = MyObj['myOptionalProp']['myProp1']; // Doesn't work
type Test2 = MyObj['myOptionalProp']['myProp2']; // Doesn't work
TypeScript引发此错误:
Property 'myProp1' does not exist on type 'MyOptionalPropObj | undefined'.ts(2339)
访问类型时是否有断言的方法?就像
myObj.myOptionalProp!.myProp1
可是type
秒?
在本例中,MyObj
类型是在我们的情况下自动生成的,特别是GraphQL代码生成器,并且我们无法控制其结构。我们可以简单地直接使用类型SomeType
,但这目前不是一个选择。
自动生成的类型示例为:
export type TestQuery = (
{ __typename?: 'Query' }
& { profile: Maybe<(
{ __typename?: 'Profile' }
& Pick<Profile, 'id' | 'name' | 'updatedAt' | 'createdAt'>
& { owner: Maybe<(
{ __typename?: 'User' }
& Pick<User, 'id' | 'displayName'>
)>, users: Maybe<Array<(
{ __typename?: 'User' }
& Pick<User, 'id' | 'displayName'>
)>> }
)> }
);
在此示例中,我们无法访问owner
的{{1}}属性,因为所有者可能未定义。
profile
答案 0 :(得分:2)
如果属性是可选的,则其类型将与未定义的联合,并且由于只能访问联合的公共属性,因此原始类型的所有属性都将不可访问。
您需要从联合中删除undefined
。预定义的条件类型Exclude
将达到目的:
interface MyObj {
myOptionalProp?: MyOptionalPropObj; // OPTIONAL
}
interface MyOptionalPropObj {
myProp1: string;
myProp2?: number;
}
type Test1 = Exclude<MyObj['myOptionalProp'], undefined>['myProp1']; //ok
type Test2 = Exclude<MyObj['myOptionalProp'], undefined>['myProp2']; // ok