Typescript : 제네릭 유형에 대한 오버로딩 및 검사

늑대 359

이 인터페이스가 있습니다.

export interface ICRUDService<T extends IModel> {

    save(item: T): Promise<void>;
    save(items: T[]): Promise<void>;
    save(item: IRemoteData<T>): Promise<void>;
    save(items: IRemoteData<T>[]): Promise<void>;
    save(item: Partial<T>): Promise<void>;
}

및 구현 :

export abstract class AbstractCRUDServiceImpl<T extends IModel> implements ICRUDService<T> {

    async save(item: T): Promise<void>;
    async save(items: T[]): Promise<void>;
    async save(item: IRemoteData<T>): Promise<void>;
    async save(items: IRemoteData<T>[]): Promise<void>;
    async save(item: Partial<T>): Promise<void>;

    async save(item: any): Promise<void> {

        if (typeof item === T)
            // ...

    }
}

그러나 그것은 말한다 :

'T'는 유형만을 의미하지만 여기서는 값으로 사용됩니다 .ts (2693) '

이 문제를 해결하는 올바른 방법은 무엇입니까?

알렉스 웨인

코드가 실제로 실행 중이면 모든 입력 정보가 ​​사라집니다. 따라서 런타임에 객체가 무엇인지 파악하기 위해 유형에 의존 할 수 없습니다.

대신 값에 원하는 유형 과 동일한 기능 이 있는지 확인해야합니다 .

둘째, 구현 함수의 인수는 재정의의 모든 유형을 합친 유형이어야합니다.


IModel다음 IRemoteData같이 설정되어 있다고 가정 해 보겠습니다 .

interface IRemoteData<T> {
  remoteData: T
}
interface IModel {
  id: number
}

이제 다음과 같은 구현을 갖게됩니다.

export abstract class AbstractCRUDServiceImpl<T extends IModel> implements ICRUDService<T> {
  async save(item: T): Promise<void>;
  async save(items: T[]): Promise<void>;
  async save(item: IRemoteData<T>): Promise<void>;
  async save(items: IRemoteData<T>[]): Promise<void>;
  async save(item: Partial<T>): Promise<void>;
  async save(items: IRemoteData<T> | T): Promise<void>; // Added this override

  async save(item: T | T[] | IRemoteData<T> | IRemoteData<T>[] | Partial<T>): Promise<void> {
    if (Array.isArray(item)) {
      // item is array in this scope, iterate over each item and save them
      for (const singleItem of item) {
        await this.save(singleItem)
      }
    } else {
      // item is not an array in this scope
      if ('id' in item) {
        item // T | Partial<T>
      } else {
        item // IRemoteData<T>
      }
    }
  }
}

해당 조건부의 각 분기에서 해당 유형을 처리합니다.

유형과 비교하지 않지만 원하는 유형의 기능이 있는지 확인합니다. 를 사용 Array.isArray()하여 배열인지 확인할 수 있으며 조건부 유형 스크립트에서 사용될 때 그것이 배열임을 알 수 있으며 해당 유형은 더 이상 공용체에서 배열이 아닌 유형이 될 수 없습니다.

를 사용 'propName' in item하여 원하는 유형 중 하나에 만 존재할 수있는 속성을 정의하는지 테스트 할 수 있습니다 .

그런 다음 else절을 사용하여 아직 필터링하지 않은 모든 유형과 일치 시킬 수 있습니다 .

운동장


이제 추가 재정의에 유의하십시오.

async save(items: IRemoteData<T> | T): Promise<void>; // Added this override

이것은 조건부의 배열 처리 분기에 필요합니다. 문제는 그것이 배열이라는 것을 알고 나면 그것이 배열 인 것을 알지 못한다는 것입니다. 따라서 항목을 반복 할 때 각 항목의 유형은 다음과 같습니다.

T | IRemoteData<T>

따라서 특정 경우를 처리하려면 과부하가 필요합니다.

async save(items: IRemoteData<T> | T): Promise<void>; // Added this override

또는 재정의를 완전히 제거 할 수 있습니다. 오버라이드는 유형의 통합이 될 수있는 인수가 하나만있을 때 유용하지 않으며 훨씬 더 유용한 특정 인수 시그니처가 다른 유형을 반환합니다. 이것은 하나의 함수 정의만으로는 할 수없는 일입니다.

예를 들면 :

function foo(a: number): string
function foo(a: string): number
function foo(a: number|string): number|string {
  if (typeof a === 'string') {
    return 123
  } else {
    return 'a string'
  }
}

이 오버로드는 특정 인수 유형을 특정 반환 유형에 연결합니다. 그러나 당신의 함수는 그것을 필요로하지 않으며, 인수가 단순히 많은 것들을 결합한 단일 함수로 표현 될 수 있습니다.

이것이 작동한다는 것을 의미합니다.

export abstract class AbstractCRUDServiceImpl<T extends IModel> {
  async save(item: T | T[] | IRemoteData<T> | IRemoteData<T>[] | Partial<T>): Promise<void> {
    if (Array.isArray(item)) {
      // item is array in this scope, iterate over each item and save them
      for (const singleItem of item) {
        await this.save(singleItem)
      }
    } else {
      // item is not an array in this scope
      if ('id' in item) {
        item // T | Partial<T>
      } else {
        item // IRemoteData<T>
      }
    }
  }
}

운동장

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

제네릭 유형을 사용한 TypeScript 함수 오버로딩

분류에서Dev

제네릭 유형의 비 제네릭 속성에 대한 유효성 검사

분류에서Dev

Typescript에서 제네릭에 대한 컴파일 검사가 없습니까?

분류에서Dev

제네릭 팩토리에 대한 제네릭 및 유형 추론

분류에서Dev

Enum 및 제네릭을 사용하여 typescript에서 요일 가져 오기

분류에서Dev

'모든'유형에 대한 Typescript 검사

분류에서Dev

Typescript 2.x에서 유형 매개 변수 및 'keyof'로 제네릭을 제한하는 방법을 이해하려고합니다.

분류에서Dev

제네릭 및 리플렉션에 대한 Java 기본 사항

분류에서Dev

Typescript 제네릭 유형 사용

분류에서Dev

관련 유형 및 제네릭 사용 오류

분류에서Dev

Typescript에서 enum을 제네릭 유형으로 사용할 때 호환되지 않는 유형

분류에서Dev

TypeScript : 제한된 제네릭 형식에서 Partial <T> 사용 문제

분류에서Dev

TypeScript 제네릭 함수에 대한 제네릭 유형 별칭을 만드는 방법은 무엇입니까?

분류에서Dev

제네릭 유형으로의 Aeson 디코딩 문제 유형 검사

분류에서Dev

경로 종속 유형 및 제네릭

분류에서Dev

Java에서 제네릭 및 유형 추론 사용 문제

분류에서Dev

C # 제네릭 대리자에 대한 C ++ 해당 구문 및 람다 사용

분류에서Dev

Swift 용 LLDB : 제네릭 유형에 대한 사용자 정의 유형 요약

분류에서Dev

angular2 / 제네릭 유형을 사용한 typescript 클래스 상속

분류에서Dev

Typescript 제네릭, 제약 조건 및 리터럴 유형

분류에서Dev

제네릭 및 술어가있는 Typescript Array 프로토 타입 및 유형 유추 허용

분류에서Dev

제네릭 및 유형에 대해 약간 혼동

분류에서Dev

Typescript-통합 유형 및 제네릭 유형이 비 호환성 오류를 발생시킵니다.

분류에서Dev

제네릭이 아닌 메소드로 일반 메소드를 대체 할 때 서브 서명 및 검사되지 않은 규칙이 리턴 유형에서이 방식으로 작동하는 이유는 무엇입니까?

분류에서Dev

프리미티브 및 객체 유형에 대한 메서드 오버로딩

분류에서Dev

RxJ 및 typescript를 사용한 유형 추론에 대한 흥미로운 이야기

분류에서Dev

반환 유형 및 매개 변수에 제네릭 사용

분류에서Dev

스택 오버 플로우 문제에 제네릭 형식 이진 검색 트리 결과에 대한 방법을 제거

분류에서Dev

제네릭 유형의 특수한 경우에 대한 Scala 메서드 오버로드

Related 관련 기사

  1. 1

    제네릭 유형을 사용한 TypeScript 함수 오버로딩

  2. 2

    제네릭 유형의 비 제네릭 속성에 대한 유효성 검사

  3. 3

    Typescript에서 제네릭에 대한 컴파일 검사가 없습니까?

  4. 4

    제네릭 팩토리에 대한 제네릭 및 유형 추론

  5. 5

    Enum 및 제네릭을 사용하여 typescript에서 요일 가져 오기

  6. 6

    '모든'유형에 대한 Typescript 검사

  7. 7

    Typescript 2.x에서 유형 매개 변수 및 'keyof'로 제네릭을 제한하는 방법을 이해하려고합니다.

  8. 8

    제네릭 및 리플렉션에 대한 Java 기본 사항

  9. 9

    Typescript 제네릭 유형 사용

  10. 10

    관련 유형 및 제네릭 사용 오류

  11. 11

    Typescript에서 enum을 제네릭 유형으로 사용할 때 호환되지 않는 유형

  12. 12

    TypeScript : 제한된 제네릭 형식에서 Partial <T> 사용 문제

  13. 13

    TypeScript 제네릭 함수에 대한 제네릭 유형 별칭을 만드는 방법은 무엇입니까?

  14. 14

    제네릭 유형으로의 Aeson 디코딩 문제 유형 검사

  15. 15

    경로 종속 유형 및 제네릭

  16. 16

    Java에서 제네릭 및 유형 추론 사용 문제

  17. 17

    C # 제네릭 대리자에 대한 C ++ 해당 구문 및 람다 사용

  18. 18

    Swift 용 LLDB : 제네릭 유형에 대한 사용자 정의 유형 요약

  19. 19

    angular2 / 제네릭 유형을 사용한 typescript 클래스 상속

  20. 20

    Typescript 제네릭, 제약 조건 및 리터럴 유형

  21. 21

    제네릭 및 술어가있는 Typescript Array 프로토 타입 및 유형 유추 허용

  22. 22

    제네릭 및 유형에 대해 약간 혼동

  23. 23

    Typescript-통합 유형 및 제네릭 유형이 비 호환성 오류를 발생시킵니다.

  24. 24

    제네릭이 아닌 메소드로 일반 메소드를 대체 할 때 서브 서명 및 검사되지 않은 규칙이 리턴 유형에서이 방식으로 작동하는 이유는 무엇입니까?

  25. 25

    프리미티브 및 객체 유형에 대한 메서드 오버로딩

  26. 26

    RxJ 및 typescript를 사용한 유형 추론에 대한 흥미로운 이야기

  27. 27

    반환 유형 및 매개 변수에 제네릭 사용

  28. 28

    스택 오버 플로우 문제에 제네릭 형식 이진 검색 트리 결과에 대한 방법을 제거

  29. 29

    제네릭 유형의 특수한 경우에 대한 Scala 메서드 오버로드

뜨겁다태그

보관