[typescript] Typescript 인터페이스 내의 모든 속성을 선택 사항으로 설정

내 응용 프로그램에 인터페이스가 있습니다.

interface Asset {
  id: string;
  internal_id: string;
  usage: number;
}

이는 포스트 인터페이스의 일부입니다.

interface Post {
  asset: Asset;
}

또한 자산 개체가 부분적으로 만 구성 될 수있는 초안 게시 용 인터페이스도 있습니다.

interface PostDraft {
  asset: Asset;
}

나는 PostDraft객체가 부분 자산 객체를 가지 도록 허용 하면서 거기있는 속성에 대한 유형을 계속 확인하고 싶습니다 (그래서 그냥으로 바꾸고 싶지 않습니다 any).

기본적으로 다음을 생성 할 수있는 방법을 원합니다.

interface AssetDraft {
  id?: string;
  internal_id?: string;
  usage?: number;
}

Asset인터페이스 를 완전히 다시 정의하지 않고 이를 수행하는 방법이 있습니까? 그렇지 않다면이 상황에서 내 유형을 정렬하는 현명한 방법은 무엇입니까?



답변

선택적 속성이있는 추가 인터페이스를 생성하지 않고는 TypeScript <2.1에서는 불가능합니다. 그러나 이것은 TypeScript 2.1+에서 매핑 된 유형을 사용하여 가능합니다.

이렇게하려면 Partial<T>TypeScript가 기본적으로 제공 하는 유형을 사용하십시오 .

interface PostDraft {
    asset: Partial<Asset>;
}

이제의 모든 속성 asset이 선택 사항이므로 다음을 수행 할 수 있습니다.

const postDraft: PostDraft = {
    asset: {
        id: "some-id"
    }
};

Partial<T>

Partial<T>되고 정의 제공된 유형의 모든 속성 선택하십시오 (사용하게 매핑 된 형태로 ?토큰).

type Partial<T> = {
    [P in keyof T]?: T[P];
};

여기핸드북에서 매핑 된 유형에 대해 자세히 읽어보십시오 .

깊은 부분

객체에 대해 재귀 적으로 작동하는 부분 구현을 원하는 경우 TS 4.1+에서 다음 유형을 사용할 수 있습니다.

type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};


답변

인터페이스의 속성은 선택 사항이 아닙니다. 동일한 인터페이스를 선택 사항으로 한 번, 필수 사항으로 한 번 사용할 수 없습니다.

당신이 할 수있는 일은에 대한 선택적 속성이있는 인터페이스와에 대한 AssetDraft필수 속성이있는 클래스를 갖는 것입니다 Asset.

interface AssetDraft {
    id?: string;
    internal_id?: string;
    usage?: number;
}

class Asset {
    static DEFAULT_ID = "id";
    static DEFAULT_INTERNAL_ID = "internalid";
    static DEFAULT_USAGE = 0;

    id: string;
    internal_id: string;
    usage: number;

    constructor(draft: AssetDraft) {
        this.id = draft.id || Asset.DEFAULT_ID;
        this.internal_id = draft.internal_id || Asset.DEFAULT_INTERNAL_ID;
        this.usage = draft.usage || Asset.DEFAULT_USAGE;
    }
}

여기서 기본값은 정적 멤버이지만 다른 방법으로 가져 오거나 누락 된 경우 오류를 발생시킬 수 있습니다.

이 방법은 서버 (또는 이와 유사한 것)에서받은 json으로 작업 할 때 매우 편안하고 인터페이스는 json 데이터를 나타내고 클래스는 json을 초기 값으로 사용하여 구성된 실제 모델입니다.


답변

명시 적 AssetDraft인터페이스를 원하면 extends및 조합을 사용합니다 Partial.

interface Asset {
  id: string;
  internal_id: string;
  usage: number;
}

interface AssetDraft extends Partial<Asset> {}


답변

David Sherret 외에도 Partial<T>주제에 대한 더 나은 이해를 위해 유형 없이 직접 구현할 수있는 방법에 대해 내 측에서 몇 줄만 대답 합니다.

interface IAsset {
  id: string;
  internal_id: string;
  usage: number;
}

interface IPost {
  asset: IAsset;
}

interface IPostDraft {
  asset: { [K in keyof IAsset]?: IAsset[K] };
}

const postDraft: IPostDraft = {
  asset: {
    usage: 123
  }
};


답변

빈 개체를 강제 캐스팅하는 방법은?

const draft = <PostDraft>{}
draft.id = 123
draft.internal_id = 456
draft.usage = 789

정말로 이것이 필요하다면 선택 속성과 유형 속성을 모두 만드는 템플릿에서 d.ts 인터페이스를 항상 생성 할 수 있습니다.

Nitzan이 지적했듯이 Typescript 인터페이스 속성은 선택 사항이거나 그렇지 않습니다.


답변