TypeScript에서 제네릭 유형을 재귀 적으로 추론 할 수 있습니까?

라파엘 고메 시즈

예를 들어 다음 코드를 사용하십시오.

const [divEl, spanEl] = createElements([
    ['div', { id: 'test' }, [
        ['a', { href: 'test' }, [
            ['img', { src: 'test' }, null]
        ]],
        ['img', { href: 'test' }, null]
    ]],
    ['span', null, null]
]);

나는 타이프가의 유형 추론 할 divEl수 할 수 HTMLDivElement및 유형 spanEl이어야합니다을 HTMLSpanElement. 또한 주어진 속성을 확인하고 유추 된 유형에 따라 오류를 표시하기를 원합니다 (예 : 속성 ['img', { href: 'test' }, null]없기 때문에에 오류를 표시해야 함 ).HTMLImageElementhref

몇 가지 조사 끝에 지금까지 내가 가진 것입니다.

type ElementTag = keyof HTMLElementTagNameMap;

type ElementAttributes<T extends ElementTag> = {
    [K in keyof HTMLElementTagNameMap[T]]?: Partial<HTMLElementTagNameMap[T][K]> | null;
};

type ElementArray<T extends ElementTag> = [
    T,
    ElementAttributes<T> | null,
    ElementArray<ElementTag>[] | string | null
];

type MappedElementArray<T> = {
    [K in keyof T]: T[K] extends ElementArray<infer L> ? HTMLElementTagNameMap[L] : never;
};

// This is the signature for the createElements function.
type CreateElements = <T extends ElementArray<ElementTag>[] | []>(
    array: T
) => MappedElementArray<T>;

ElementArray<ElementTag>[]일반적인 것으로 변경 해야하지만 진행 방법을 잘 모르겠습니다.

이것이 가능할까요?

수동으로 할 수 있다는 것을 알고 있지만 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, ...예쁘지 않습니다.

Gerrit0

(일부 답변)

TypeScript는 재귀 유형을 좋아하지 않습니다. 추론이 필요하지 않는 한 대부분이 문제를 해결할 수 있지만 여기에서 필요하기 때문에 TS가 마지막 단계를 수행하는 것이 가능하지 않다고 생각합니다.

다음 기능 중 하나를 사용할 수 있습니다.

  1. 반환 유형이 올바른 반환 유형을 가진 튜플이라고 추론하십시오.
  2. 전달 된 배열을 자세히 typecheck

첫 번째는 쉽습니다. 우리는 필요 TcreateElements차별 노동 조합을 연장 할 수 있습니다. 당신은 이미 이것을 가지고 있지만 이것은 그것을 보는 방법이 약간 다릅니다.

type DiscriminatedElements = {
    // you can, of course, do better than unknown here.
    [K in keyof HTMLElementTagNameMap]: readonly [K, Partial<HTMLElementTagNameMap[K]> | null, unknown]
}[keyof HTMLElementTagNameMap]

type ToElementTypes<T extends readonly DiscriminatedElements[]> = {
    [K in keyof T]: T[K] extends [keyof HTMLElementTagNameMap, any, any] ? HTMLElementTagNameMap[T[K][0]] : never
}

declare const createElements: <T extends readonly DiscriminatedElements[] | []>(
    array: T
) => ToElementTypes<T>

createElements([
    ['span', {}, null]
]) // [HTMLSpanElement]

두 번째는 조금 더 까다 롭습니다. 앞서 말했듯이 TS는 재귀 유형을 좋아하지 않습니다. GH # 26980을 참조하십시오 . 즉, 검사를 위해 임의의 깊이 유형을 생성하기 위해 작업 할 수 있지만이 유형을 추론과 결합하려고하면 TS는 그것이 잠재적으로 무한하다는 것을 알게 될 것입니다.

type DiscriminatedElements = {
    [K in keyof HTMLElementTagNameMap]: readonly [K, Partial<HTMLElementTagNameMap[K]> | null]
}[keyof HTMLElementTagNameMap]

type NumberLine = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
type CreateElementArray<T extends readonly [any, any], N extends number> = T extends readonly [infer A, infer B] ? {
    done: readonly [A, B, null],
    recurse: readonly [A, B, null | readonly CreateElementArray<DiscriminatedElements, NumberLine[N]>[]]
}[N extends 0 ? 'done' : 'recurse'] : never

// Increase up N and NumberLine as required
type ElementItem = CreateElementArray<DiscriminatedElements, 4>

declare const createElements: (
    array: readonly ElementItem[]
) => HTMLElement[];


const [divEl, spanEl] = createElements([
    ['div', { id: 'test' }, [
        ['a', { href: 'test' }, [
            ['img', { src: 'test' }, null]
        ]],
        ['img', { href: 'test' }, null] // error, as expected
    ]],
    ['span', null, null]
]);

가변 튜플이 여기서 도움이되지 않는다고 생각합니다. 그들은 언어에 대한 멋진 추가가 될 것이지만 여기서 모델링하려는 문제를 해결하지는 마십시오.

두 세계를 최대한 활용할 수있는 해결책은 HTML 요소를 튜플의 세 번째 항목으로 받아들이고 createElements해당 배열 내에서 간단히 호출 하는 것입니다.

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

작업 유형을 표현식에 지정하지 않고 제네릭 유형으로 추론 할 수 있습니까?

분류에서Dev

다른 제네릭 클래스에서 유형 매개 변수로도 사용될 때 제네릭 유형을 추론 할 수 없습니다.

분류에서Dev

Typescript 제네릭 : 함수 인수 유형에서 유형을 추론합니까?

분류에서Dev

TypesScript에서 제네릭 유형을 객체 인덱스 유형으로 사용할 수 있습니까?

분류에서Dev

Rust의 재귀 열거 형에서 일반 함수 유형을 추론 할 수 없습니다.

분류에서Dev

TypeScript는 T가 조건부 일 때 제네릭 유형을 추론 할 수 없습니다.

분류에서Dev

TypeScript의 제네릭 유형에서 제네릭 유형을 추론하는 방법이 있습니까?

분류에서Dev

Swift 열거 형을 제네릭으로 만들 수 있으므로 해당 케이스를 사용하여 제네릭 클래스의 유형을 추론 할 수 있습니까?

분류에서Dev

typescript에서 중첩 제네릭 유형을 추론합니까?

분류에서Dev

TypeScript가 재귀 함수 유형을 추론 할 수없는 이유

분류에서Dev

TypeScript에서 선택적 속성을 어떻게 추론 할 수 있습니까?

분류에서Dev

여러 제네릭 유형 매개 변수에 동일한 제약 조건을 적용 할 수 있습니까?

분류에서Dev

'모든'유형에서 유형을 추론 할 수 있습니까?

분류에서Dev

typescript의 매핑 된 유형에서 함수의 반환 유형을 추론 할 수 있습니까?

분류에서Dev

어떤 이유로 컴파일러가 제네릭 클래스 생성자 유형을 추론 할 수 없습니까?

분류에서Dev

제네릭 프로그래밍을 위해 변수 유형에 액세스 할 수 있습니까?

분류에서Dev

제네릭 유형을 Interface, new ()로 제한 할 수 있습니까?

분류에서Dev

Typescript에서 호출하지 않고 함수의 제네릭 유형을 설정할 수 있습니까?

분류에서Dev

제네릭 유형을 제한하면서 제네릭 클래스를 확장 할 수 있습니까?

분류에서Dev

Kotlin-제네릭 유형 매개 변수를 추론 할 수 있나요?

분류에서Dev

구체적 유형으로 객체를 인스턴스화 할 때 변수에 제네릭 유형을 사용할 수없는 이유는 무엇입니까?

분류에서Dev

(ASDF 3) 서브 디렉토리에 시스템을 재귀 적으로로드 할 수 있습니까?

분류에서Dev

TS : 왜 제네릭 유형 변수에 유효하지 않은 유형을 할당 할 수 있습니까?

분류에서Dev

형식화 된 함수가 개체 속성에 재귀 적으로 액세스 할 수 있습니까?

분류에서Dev

Stata에서 파일 이름을 재귀 적으로 지정할 수 있습니까?

분류에서Dev

Typescript에서이 유형을 추출 할 수 있습니까?

분류에서Dev

제네릭 유형을 분할 할 수 있습니까?

분류에서Dev

Common Lisp에서 재귀 유형을 정의 할 수 있습니까?

분류에서Dev

typescript의 객체에서 제네릭을 사용할 수 있습니까?

Related 관련 기사

  1. 1

    작업 유형을 표현식에 지정하지 않고 제네릭 유형으로 추론 할 수 있습니까?

  2. 2

    다른 제네릭 클래스에서 유형 매개 변수로도 사용될 때 제네릭 유형을 추론 할 수 없습니다.

  3. 3

    Typescript 제네릭 : 함수 인수 유형에서 유형을 추론합니까?

  4. 4

    TypesScript에서 제네릭 유형을 객체 인덱스 유형으로 사용할 수 있습니까?

  5. 5

    Rust의 재귀 열거 형에서 일반 함수 유형을 추론 할 수 없습니다.

  6. 6

    TypeScript는 T가 조건부 일 때 제네릭 유형을 추론 할 수 없습니다.

  7. 7

    TypeScript의 제네릭 유형에서 제네릭 유형을 추론하는 방법이 있습니까?

  8. 8

    Swift 열거 형을 제네릭으로 만들 수 있으므로 해당 케이스를 사용하여 제네릭 클래스의 유형을 추론 할 수 있습니까?

  9. 9

    typescript에서 중첩 제네릭 유형을 추론합니까?

  10. 10

    TypeScript가 재귀 함수 유형을 추론 할 수없는 이유

  11. 11

    TypeScript에서 선택적 속성을 어떻게 추론 할 수 있습니까?

  12. 12

    여러 제네릭 유형 매개 변수에 동일한 제약 조건을 적용 할 수 있습니까?

  13. 13

    '모든'유형에서 유형을 추론 할 수 있습니까?

  14. 14

    typescript의 매핑 된 유형에서 함수의 반환 유형을 추론 할 수 있습니까?

  15. 15

    어떤 이유로 컴파일러가 제네릭 클래스 생성자 유형을 추론 할 수 없습니까?

  16. 16

    제네릭 프로그래밍을 위해 변수 유형에 액세스 할 수 있습니까?

  17. 17

    제네릭 유형을 Interface, new ()로 제한 할 수 있습니까?

  18. 18

    Typescript에서 호출하지 않고 함수의 제네릭 유형을 설정할 수 있습니까?

  19. 19

    제네릭 유형을 제한하면서 제네릭 클래스를 확장 할 수 있습니까?

  20. 20

    Kotlin-제네릭 유형 매개 변수를 추론 할 수 있나요?

  21. 21

    구체적 유형으로 객체를 인스턴스화 할 때 변수에 제네릭 유형을 사용할 수없는 이유는 무엇입니까?

  22. 22

    (ASDF 3) 서브 디렉토리에 시스템을 재귀 적으로로드 할 수 있습니까?

  23. 23

    TS : 왜 제네릭 유형 변수에 유효하지 않은 유형을 할당 할 수 있습니까?

  24. 24

    형식화 된 함수가 개체 속성에 재귀 적으로 액세스 할 수 있습니까?

  25. 25

    Stata에서 파일 이름을 재귀 적으로 지정할 수 있습니까?

  26. 26

    Typescript에서이 유형을 추출 할 수 있습니까?

  27. 27

    제네릭 유형을 분할 할 수 있습니까?

  28. 28

    Common Lisp에서 재귀 유형을 정의 할 수 있습니까?

  29. 29

    typescript의 객체에서 제네릭을 사용할 수 있습니까?

뜨겁다태그

보관