IT TIP

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

itqueen 2021. 1. 10. 19:46
반응형

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];
};

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


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

당신이 할 수있는 일은에 대한 선택적 속성이있는 인터페이스와에 대한 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;
    }
}

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

I find this way very comfortable when working with jsons that are received from the server (or something similar), the interfaces represent the json data and the classes are the actual models that are constructed using the jsons as initial values.


How about force casting an empty object e.g

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

If you really really need this then you can always generate a d.ts interface from a template that makes both the optional and typed properties.

As Nitzan pointed out, either Typescript interface properties are optional or not


In addition to David Sherret answer just a few lines from my side how it can be implemented directly without Partial<T> type for better understanding of the subject.

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
  }
};

ReferenceURL : https://stackoverflow.com/questions/39713349/make-all-properties-within-a-typescript-interface-optional

반응형