如何访问可选属性的“类型”属性?

问题描述 投票:2回答:1

请参见下面的代码段:

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中要分配给Test2myOptionalProp的嵌套属性可以正常工作。

但是。一旦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'>
    )>> }
  )> }
);

在此示例中,由于无法定义所有者,因此无法访问ownerprofile属性。

TestQuery['profile']['owner'] // Doesn't work
typescript
1个回答
0
投票

如果属性是可选的,则其类型将与未定义联合,并且由于只能访问联合的公共属性,因此原始类型的所有属性都将不可访问。

您需要从联合中删除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

Playground Link

© www.soinside.com 2019 - 2024. All rights reserved.