Typescript를 사용하여 범용 유형 중 하나 구현
22460 단어 typescript
oneOf
을 설명하려는 사례를 본 적이 있습니까?나는 여러 번 했지만, 그 전에, 나는 어쩔 수 없이 가독성과 유형 안전성 사이에서 선택을 해야 했다😑.
예를 들어 우리는 이러한 사실을 표현하고 싶다. 우리의 게임 유저는 모험하기 전에 동물 한 마리를 선택하여 그와 동행할 수 있다.그러나 게임에서 사용할 수 있는 모든 동물은 아니다. 그는 다음 두 가지 동물 중 하나만 선택해야 한다.
유형 보안 가독성
만약 우리가 유형의 안전성보다 가독성에 더 관심이 있다면, 우리는 간단하게 동물과 유저를 다음과 같이 묘사할 수 있다.
interface Animal {
id: string;
name: string;
// the animal can be ONE of the following
dog: Dog | null;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
interface Player {
id: string;
nickname: string;
level: number;
animal: Animal;
}
이런 상황에서 인터페이스는 매우 쉽게 읽을 수 있으나, 우리는 플레이어에 dog
과 wolf
을 정의할 수 있으며, Typescript는 여전히 만족스럽다.
형식 보안이 가독성을 초과하다
우리는 선수들이 둘 사이에서만 선택할 수 있다는 것을 안다🐶, 🐺, 🦅 화목하다🐭. 우리는 이 정보를 사용할 수 있습니다. 주석 // the animal can be ONE of the following
이 아니라 Typescript를 사용하여 이 점을 표현할 수 있습니다. (이것은 잠시 후에 우리에게 추가 유형의 안전을 가져다 줄 것입니다!)
간단하게 말하자면, 우리는 단지 두 가지 측면에서 시작한다.🐶, 🐺.
type Animal = {
id: string;
name: string;
} & (
| {
dog: Dog | null;
wolf: null;
}
| {
dog: null;
wolf: Wolf | null;
});
interface Player {
// ... same ...
}
이런 방식을 통해 우리는 동물이 개나 늑대일 수 있지만 둘을 동시에 가질 수 없다는 사실을 확실히 나타냈다.위의 유형을 사용하는 것은 합리적인 것 같지만 이제 이 네 가지 동물의 외관을 살펴보자.
type Animal = {
id: string;
name: string;
} & ({
dog: Dog | null;
wolf: null;
eagle: null;
mouse: null;
} | {
dog: null;
wolf: Wolf | null;
eagle: null;
mouse: null;
} | {
dog: Dog null;
wolf: Wolf null;
eagle: Eagle | null;
mouse: null;
} | {
dog: null;
wolf: null;
eagle: null;
mouse: Mouse | null;
});
interface Player {
// ... same ...
}
응😵... 지금 우리가 게임을 업데이트하면 5개, 10개 또는 15개의 새로운 동물을 추가하면 어떤 모습일지 상상할 수 있습니까?🤕
이것은 근본적으로 확장할 수 없다.
쌍방이 모두 좋게 하다
얼마나 멋있는지
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
만약 우리가 이전의 예처럼 모든 유형의 안전성을 가지고 있다고 가정한다면, 나는 이것이 매우 좋을 것이라고 생각한다.
그런데 저희가 할 수 있을까요?한 걸음 한 걸음 해 봅시다.
먼저 해야 할 일은 우리가 그것을 전달하면
{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}
위 유형에서 dog
과 같은 키를 찾으면 다음 유형을 얻을 수 있습니다.
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
우리는 이러한 유형을 OneOnly
이라고 부른다.
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
이러한 유형을 이해하고 이해해 보겠습니다.
type OneOnly<Obj, Key extends keyof Obj>
아직까지는 괜찮을 거예요.우리는 Obj
이라는 유형을 전달할 수 있으며, 이 유형의 키를 두 번째 매개 변수로 전달해야 한다.
{ [key in Exclude<keyof Obj, Key>]: null }
현재, 우리는 일반적인 두 번째 매개 변수로 전달되는 키를 제외하고 Obj
유형의 모든 키를 훑어보고 있다.이 모든 키에 대해 우리는 그들이 받아들일 수 있는 유일한 값이 null
이라고 말한다.
퍼즐의 마지막 부분:
Pick<Obj, Key>
우리는 Obj
유형에서 Key
을 추출했다.
그래서 결국 저희가 얻었어요.
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
예를 들어, dog
과 함께 사용하면 다음과 같은 결과를 얻을 수 있습니다.
type OnlyDog = OneOnly<
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
},
'dog'
>;
OnlyDog
형은 다음과 같습니다.
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
차갑다마지막 OneOf
형 중 가장 복잡한 부분을 완성했다고 생각합니다.✅.
지금, 너는 이미 보았을지도 몰라...Obj
유형을 반복해서 사용하고 키당 OneOnly
유형을 생성해야 합니다.
type OneOfByKey<T> = { [key in keyof T]: OneOnly<T, key> };
여기는 그리 화려한 것은 없지만, 이 직업은 매우 강하다!만약 우리가 이렇게 한다면
type OnlyOneAnimal = OneOfByKey<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
다음과 같은 유형이 제공됩니다.
{
dog: OneOnly<Dog>;
wolf: OneOnly<Wolf>;
eagle: OneOnly<Eagle>;
mouse: OneOnly<Mouse>;
}
그게 슈우퍼 쿨 맞나요?하지만🤔
우리는 위 유형의 모든 값의 병합 유형이 필요하다.
유사:
OneOnly<Dog> | OneOnly<Wolf> | OneOnly<Eagle> | OneOnly<Mouse>
우리는 어떻게 해야만 이 점을 할 수 있습니까?다음과 같은 몇 가지만 수행할 수 있습니다.
type ValueOf<Obj> = Obj[keyof Obj];
그러면 Obj
유형의 모든 값에 대한 결합 유형이 생성됩니다.
마지막으로, 우리의 OneOf
은 지금:
type OneOfType<T> = ValueOf<OneOfByKey<T>>;
🤩 좋아, 그렇지 않아?🤩
다음은 전체 코드 요약입니다.
type ValueOf<Obj> = Obj[keyof Obj];
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
type OneOfByKey<Obj> = { [key in keyof Obj]: OneOnly<Obj, key> };
export type OneOfType<Obj> = ValueOf<OneOfByKey<Obj>>;
그리고 우리가 지금 그것을 어떻게 사용하는지:
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
지금 가장 멋있는 일은 플레이어와 동물을 정의할 때 우리는 그 중의 한 동물만 정의할 수 있다는 것이다.0이 아니라 2가 아니라 3이 아니라 4가 아니다.오직 하나😁.
이것은 Typescript Playground입니다. 당신은 즐겁게 놀 수 있습니다.이것은 우리가 본 모든 코드와 위gif에 표시된 최종 프레젠테이션을 포함한다.
맞춤법 오류 발견?
이 블로그 글에서 맞춤법 오류, 개선할 수 있는 문장, 업데이트해야 할 내용을 발견하면git 저장소를 통해 접근해서 요청할 수 있습니다.의견을 발표하지 말고 바로 이동하여 새로운 추출 요청과 변경 사항을 열어 주십시오.
Reference
이 문제에 관하여(Typescript를 사용하여 범용 유형 중 하나 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maxime1992/implement-a-generic-oneof-type-with-typescript-22em
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
interface Animal {
id: string;
name: string;
// the animal can be ONE of the following
dog: Dog | null;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
interface Player {
id: string;
nickname: string;
level: number;
animal: Animal;
}
우리는 선수들이 둘 사이에서만 선택할 수 있다는 것을 안다🐶, 🐺, 🦅 화목하다🐭. 우리는 이 정보를 사용할 수 있습니다. 주석
// the animal can be ONE of the following
이 아니라 Typescript를 사용하여 이 점을 표현할 수 있습니다. (이것은 잠시 후에 우리에게 추가 유형의 안전을 가져다 줄 것입니다!)간단하게 말하자면, 우리는 단지 두 가지 측면에서 시작한다.🐶, 🐺.
type Animal = {
id: string;
name: string;
} & (
| {
dog: Dog | null;
wolf: null;
}
| {
dog: null;
wolf: Wolf | null;
});
interface Player {
// ... same ...
}
이런 방식을 통해 우리는 동물이 개나 늑대일 수 있지만 둘을 동시에 가질 수 없다는 사실을 확실히 나타냈다.위의 유형을 사용하는 것은 합리적인 것 같지만 이제 이 네 가지 동물의 외관을 살펴보자.type Animal = {
id: string;
name: string;
} & ({
dog: Dog | null;
wolf: null;
eagle: null;
mouse: null;
} | {
dog: null;
wolf: Wolf | null;
eagle: null;
mouse: null;
} | {
dog: Dog null;
wolf: Wolf null;
eagle: Eagle | null;
mouse: null;
} | {
dog: null;
wolf: null;
eagle: null;
mouse: Mouse | null;
});
interface Player {
// ... same ...
}
응😵... 지금 우리가 게임을 업데이트하면 5개, 10개 또는 15개의 새로운 동물을 추가하면 어떤 모습일지 상상할 수 있습니까?🤕이것은 근본적으로 확장할 수 없다.
쌍방이 모두 좋게 하다
얼마나 멋있는지
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
만약 우리가 이전의 예처럼 모든 유형의 안전성을 가지고 있다고 가정한다면, 나는 이것이 매우 좋을 것이라고 생각한다.
그런데 저희가 할 수 있을까요?한 걸음 한 걸음 해 봅시다.
먼저 해야 할 일은 우리가 그것을 전달하면
{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}
위 유형에서 dog
과 같은 키를 찾으면 다음 유형을 얻을 수 있습니다.
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
우리는 이러한 유형을 OneOnly
이라고 부른다.
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
이러한 유형을 이해하고 이해해 보겠습니다.
type OneOnly<Obj, Key extends keyof Obj>
아직까지는 괜찮을 거예요.우리는 Obj
이라는 유형을 전달할 수 있으며, 이 유형의 키를 두 번째 매개 변수로 전달해야 한다.
{ [key in Exclude<keyof Obj, Key>]: null }
현재, 우리는 일반적인 두 번째 매개 변수로 전달되는 키를 제외하고 Obj
유형의 모든 키를 훑어보고 있다.이 모든 키에 대해 우리는 그들이 받아들일 수 있는 유일한 값이 null
이라고 말한다.
퍼즐의 마지막 부분:
Pick<Obj, Key>
우리는 Obj
유형에서 Key
을 추출했다.
그래서 결국 저희가 얻었어요.
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
예를 들어, dog
과 함께 사용하면 다음과 같은 결과를 얻을 수 있습니다.
type OnlyDog = OneOnly<
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
},
'dog'
>;
OnlyDog
형은 다음과 같습니다.
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
차갑다마지막 OneOf
형 중 가장 복잡한 부분을 완성했다고 생각합니다.✅.
지금, 너는 이미 보았을지도 몰라...Obj
유형을 반복해서 사용하고 키당 OneOnly
유형을 생성해야 합니다.
type OneOfByKey<T> = { [key in keyof T]: OneOnly<T, key> };
여기는 그리 화려한 것은 없지만, 이 직업은 매우 강하다!만약 우리가 이렇게 한다면
type OnlyOneAnimal = OneOfByKey<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
다음과 같은 유형이 제공됩니다.
{
dog: OneOnly<Dog>;
wolf: OneOnly<Wolf>;
eagle: OneOnly<Eagle>;
mouse: OneOnly<Mouse>;
}
그게 슈우퍼 쿨 맞나요?하지만🤔
우리는 위 유형의 모든 값의 병합 유형이 필요하다.
유사:
OneOnly<Dog> | OneOnly<Wolf> | OneOnly<Eagle> | OneOnly<Mouse>
우리는 어떻게 해야만 이 점을 할 수 있습니까?다음과 같은 몇 가지만 수행할 수 있습니다.
type ValueOf<Obj> = Obj[keyof Obj];
그러면 Obj
유형의 모든 값에 대한 결합 유형이 생성됩니다.
마지막으로, 우리의 OneOf
은 지금:
type OneOfType<T> = ValueOf<OneOfByKey<T>>;
🤩 좋아, 그렇지 않아?🤩
다음은 전체 코드 요약입니다.
type ValueOf<Obj> = Obj[keyof Obj];
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
type OneOfByKey<Obj> = { [key in keyof Obj]: OneOnly<Obj, key> };
export type OneOfType<Obj> = ValueOf<OneOfByKey<Obj>>;
그리고 우리가 지금 그것을 어떻게 사용하는지:
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
지금 가장 멋있는 일은 플레이어와 동물을 정의할 때 우리는 그 중의 한 동물만 정의할 수 있다는 것이다.0이 아니라 2가 아니라 3이 아니라 4가 아니다.오직 하나😁.
이것은 Typescript Playground입니다. 당신은 즐겁게 놀 수 있습니다.이것은 우리가 본 모든 코드와 위gif에 표시된 최종 프레젠테이션을 포함한다.
맞춤법 오류 발견?
이 블로그 글에서 맞춤법 오류, 개선할 수 있는 문장, 업데이트해야 할 내용을 발견하면git 저장소를 통해 접근해서 요청할 수 있습니다.의견을 발표하지 말고 바로 이동하여 새로운 추출 요청과 변경 사항을 열어 주십시오.
Reference
이 문제에 관하여(Typescript를 사용하여 범용 유형 중 하나 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/maxime1992/implement-a-generic-oneof-type-with-typescript-22em
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
type OneOnly<Obj, Key extends keyof Obj>
{ [key in Exclude<keyof Obj, Key>]: null }
Pick<Obj, Key>
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
type OnlyDog = OneOnly<
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
},
'dog'
>;
{
dog: Dog;
wolf: Wolf | null;
eagle: Eagle | null;
mouse: Mouse | null;
}
type OneOfByKey<T> = { [key in keyof T]: OneOnly<T, key> };
type OnlyOneAnimal = OneOfByKey<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
{
dog: OneOnly<Dog>;
wolf: OneOnly<Wolf>;
eagle: OneOnly<Eagle>;
mouse: OneOnly<Mouse>;
}
OneOnly<Dog> | OneOnly<Wolf> | OneOnly<Eagle> | OneOnly<Mouse>
type ValueOf<Obj> = Obj[keyof Obj];
type OneOfType<T> = ValueOf<OneOfByKey<T>>;
type ValueOf<Obj> = Obj[keyof Obj];
type OneOnly<Obj, Key extends keyof Obj> = { [key in Exclude<keyof Obj, Key>]: null } & Pick<Obj, Key>;
type OneOfByKey<Obj> = { [key in keyof Obj]: OneOnly<Obj, key> };
export type OneOfType<Obj> = ValueOf<OneOfByKey<Obj>>;
type Animal = {
id: string;
name: string;
} & OneOf<{
dog: Dog;
wolf: Wolf;
eagle: Eagle;
mouse: Mouse;
}>;
interface Player {
// ... same ...
}
이 블로그 글에서 맞춤법 오류, 개선할 수 있는 문장, 업데이트해야 할 내용을 발견하면git 저장소를 통해 접근해서 요청할 수 있습니다.의견을 발표하지 말고 바로 이동하여 새로운 추출 요청과 변경 사항을 열어 주십시오.
Reference
이 문제에 관하여(Typescript를 사용하여 범용 유형 중 하나 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/maxime1992/implement-a-generic-oneof-type-with-typescript-22em텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)