请参见下面的代码段:
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
的profile
属性。
TestQuery['profile']['owner'] // Doesn't work
如果属性是可选的,则其类型将与未定义联合,并且由于只能访问联合的公共属性,因此原始类型的所有属性都将不可访问。
您需要从联合中删除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