TypeScript에서 공용체 유형 오버로딩

damix911

f인수와 반환 유형이 공용체 유형이지만 묶여 있는 함수를 정의하고 싶습니다 . , 호출 f(anInputType)aCorrespondingOutputType결과 를 얻습니다 . TypeScript 4.1.3에서 작동하는 것 같습니다.

class Input1 {
    type1Input: string = "I am type 1!";
}

class Input2 {
    type2Input: string = "I am type 2!";
}

interface Output1 {
    type1Output: string;
}

interface Output2 {
    type2Output: string;
}

export type Input = Input1 | Input2;
export type Output = Output1 | Output2;

function f(_input: Input1): Output1;
function f(_input: Input2): Output2;
function f(_input: Input): Output {
    return null as any as Output;
}

const input = new Input2();

const output = f(input);
output.type2Output // Compiles because the compiler can figure out that output is of type Output2

그러나 (내) 실생활에서 입력은 WebGL 객체 여야합니다. Input1으로 WebGLTextureInput2바꾼 동일한 것이 WebGLBuffer컴파일되지 않습니다.

interface Output1 {
    type1Output: string;
}

interface Output2 {
    type2Output: string;
}

export type Output = Output1 | Output2;

function f(_input: WebGLTexture): Output1;
function f(_input: WebGLBuffer): Output2;
function f(_input: WebGLTexture | WebGLBuffer): Output {
    return null as any as Output;
}

const canvas = document.createElement("canvas")!;
const gl = canvas.getContext("webgl")!;
const input = gl.createBuffer()!;

const output = f(input);
output.type2Output // Does not compile because the compiler thinks that output is of type Output1

내가 뭔가를 놓치고 있습니까?

나는 다음 TypeScript 문제를 읽고 있습니다.

다음과 같은 다른 질문도 있습니다.

하지만 문제는 기존 유형 ( 예 : WebGL 객체)과 사용자 정의 클래스를 사용하는 동작의 차이 입니다.

사실 저는 Alex 아이디어를 채택하고 있습니다.

장황 해 보이지만 단일 구현으로 벗어날 수 있습니다. 앱의 다른 부분이 구성되는 방식 때문에 나에게는 다소 유리하지 않습니다. 어딘가에서 뭔가 추악하게 보일 것입니다. 그러나 이것은 지금은 좋습니다! 감사!

아래 실제 코드.

export type WebGLResource =
  { texture: WebGLTexture } |
  { buffer: WebGLBuffer } |
  { program: WebGLProgram } |
  { renderbuffer: WebGLRenderbuffer } |
  { framebuffer: WebGLFramebuffer };
export type ResourceMeta = TextureMeta | BufferMeta | ProgramMeta | RenderbufferMeta | FramebufferMeta;

function getMeta(<...omitted params...> resource: { texture: WebGLTexture }, required: true): TextureMeta;
function getMeta(<...omitted params...> resource: { buffer: WebGLBuffer }, required: true): BufferMeta;
function getMeta(<...omitted params...> resource: { program: WebGLProgram }, required: true): ProgramMeta;
function getMeta(<...omitted params...> resource: { renderbuffer: WebGLRenderbuffer }, required: true): RenderbufferMeta;
function getMeta(<...omitted params...> resource: { framebuffer: WebGLFramebuffer }, required: true): FramebufferMeta;
function getMeta(<...omitted params...> resource: { texture: WebGLTexture }, required: false): TextureMeta | null;
function getMeta(<...omitted params...> resource: { texture: WebGLBuffer }, required: false): BufferMeta | null;
function getMeta(<...omitted params...> resource: { buffer: WebGLProgram }, required: false): ProgramMeta | null;
function getMeta(<...omitted params...> resource: { renderbuffer: WebGLRenderbuffer }, required: false): RenderbufferMeta | null;
function getMeta(<...omitted params...> resource: { framebuffer: WebGLFramebuffer }, required: false): FramebufferMeta | null;
function getMeta(<...omitted params...> resource: WebGLResource, required: boolean): ResourceMeta | null {
  ...
}
알렉스 웨인

Typescript는 명목이 아닌 구조적입니다. 즉, 두 유형이 동일한 모양이지만 이름이 다른 경우 동일한 유형으로 간주됩니다. 그리고 불행하게도, WebGLTexture그리고 WebGLBuffer이 나타납니다 같은 모양을 가지고 있습니다.

VSCode 또는 typescript 플레이 그라운드에서 이러한 유형 중 하나를 cmd + 클릭 (또는 Ctrl + 클릭)하면 선언 된 방법을 볼 수 있습니다. 이 두 선언은 다음과 같습니다.

interface WebGLTexture extends WebGLObject {}
interface WebGLBuffer extends WebGLObject {}

슬프게도 두 유형은 단순히 변경되지 않은 WebGLObjects 로 선언됩니다 . Typescript는 그들을 구분할 수 없습니다. 따라서 두 번째 함수 오버로드를 트리거하려고하면 typescript는 첫 번째 오버로드가 일치 함을 인식하고이를 사용합니다.

이 인위적인 코드에서 더 나은 솔루션을 조언하기는 어렵지만 여기서 다른 접근 방식을 원할 것입니다.


전달하는 내용을 명확하게하는 키가있는 객체를 대신 받아 들일 수 있습니까? 이렇게하면 서로 다른 오버로드와 서로 다른 인수 유형이 있습니다.

function f(_input: { texture: WebGLTexture }): Output1;
function f(_input: { buffer: WebGLBuffer }): Output2;
function f(_input: { texture?: WebGLTexture, buffer?: WebGLBuffer }): Output {
    return null as any as Output;
}

const canvas = document.createElement("canvas")!;
const gl = canvas.getContext("webgl")!;

const buffer = gl.createBuffer()!;
const texture = gl.createTexture()!;

f({ texture }).type1Output; // works
f({ buffer }).type2Output; // works

운동장

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Typescript 공용체 유형에서 오류가 발생합니다.

분류에서Dev

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

분류에서Dev

TypeScript : 인터페이스에서 동적으로 공용체 유형 생성

분류에서Dev

AMD 로딩으로 TypeScript에서 유형별로 객체 가져 오기

분류에서Dev

AMD 로딩으로 TypeScript에서 유형별로 객체 가져 오기

분류에서Dev

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

분류에서Dev

typescript가 유형 공용체에 유형 오류를 제공하는 이유는 무엇입니까?

분류에서Dev

TypeScript : 공용체 유형을 객체 유형의 값으로 다시 매핑

분류에서Dev

오버로드 서명, 공용체 유형 및 "이 호출과 일치하는 오버로드 없음"오류

분류에서Dev

Typescript : 유사한 개체의 공용체를 개체 유형으로 변환

분류에서Dev

React Proptypes 공용체 유형 Breakpoint에서 오류 발생

분류에서Dev

배열에서 객체로 TypeScript 유형

분류에서Dev

C-매크로를 사용하여 다른 구조체 유형 인수로 메서드 오버로딩

분류에서Dev

TypeScript에서 TypeScript 객체 유형을 Object.values ()와 같은 공용체 유형으로 변환하는 방법은 무엇입니까?

분류에서Dev

다른 반환 유형을 사용한 메서드 오버로딩

분류에서Dev

유형 스크립트에서 구별 된 공용체를 함수 오버로드와 결합하는 방법

분류에서Dev

함수 오버로딩 : 다양한 유형의 오버로드 된 함수에 대한 용어?

분류에서Dev

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

분류에서Dev

Typescript의 공용체에서 복합 유형 참조

분류에서Dev

유형 키에서 개체의 공용체 유형 만들기

분류에서Dev

단일 함수에서 여러 캐스팅 유형 사용 (c 오버로딩 해결 방법)

분류에서Dev

TypeScript 공용체 함수 유형

분류에서Dev

typescript의 공용체 반환 유형

분류에서Dev

Typescript 공용체 유형 추론

분류에서Dev

공용체 유형에 속성 사용

분류에서Dev

오버로딩없이 유니온에서 Typecast 오버로딩 + =

분류에서Dev

TypeScript가 공용체 유형에 대한 오류를보고하는 이유는 무엇입니까?

분류에서Dev

차이 공용체 유형 및 구별 된 공용체 typescript / F #

분류에서Dev

열거 형 유형에 대한 연산자 오버로딩

Related 관련 기사

  1. 1

    Typescript 공용체 유형에서 오류가 발생합니다.

  2. 2

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

  3. 3

    TypeScript : 인터페이스에서 동적으로 공용체 유형 생성

  4. 4

    AMD 로딩으로 TypeScript에서 유형별로 객체 가져 오기

  5. 5

    AMD 로딩으로 TypeScript에서 유형별로 객체 가져 오기

  6. 6

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

  7. 7

    typescript가 유형 공용체에 유형 오류를 제공하는 이유는 무엇입니까?

  8. 8

    TypeScript : 공용체 유형을 객체 유형의 값으로 다시 매핑

  9. 9

    오버로드 서명, 공용체 유형 및 "이 호출과 일치하는 오버로드 없음"오류

  10. 10

    Typescript : 유사한 개체의 공용체를 개체 유형으로 변환

  11. 11

    React Proptypes 공용체 유형 Breakpoint에서 오류 발생

  12. 12

    배열에서 객체로 TypeScript 유형

  13. 13

    C-매크로를 사용하여 다른 구조체 유형 인수로 메서드 오버로딩

  14. 14

    TypeScript에서 TypeScript 객체 유형을 Object.values ()와 같은 공용체 유형으로 변환하는 방법은 무엇입니까?

  15. 15

    다른 반환 유형을 사용한 메서드 오버로딩

  16. 16

    유형 스크립트에서 구별 된 공용체를 함수 오버로드와 결합하는 방법

  17. 17

    함수 오버로딩 : 다양한 유형의 오버로드 된 함수에 대한 용어?

  18. 18

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

  19. 19

    Typescript의 공용체에서 복합 유형 참조

  20. 20

    유형 키에서 개체의 공용체 유형 만들기

  21. 21

    단일 함수에서 여러 캐스팅 유형 사용 (c 오버로딩 해결 방법)

  22. 22

    TypeScript 공용체 함수 유형

  23. 23

    typescript의 공용체 반환 유형

  24. 24

    Typescript 공용체 유형 추론

  25. 25

    공용체 유형에 속성 사용

  26. 26

    오버로딩없이 유니온에서 Typecast 오버로딩 + =

  27. 27

    TypeScript가 공용체 유형에 대한 오류를보고하는 이유는 무엇입니까?

  28. 28

    차이 공용체 유형 및 구별 된 공용체 typescript / F #

  29. 29

    열거 형 유형에 대한 연산자 오버로딩

뜨겁다태그

보관