K를 사용할 때 T [K]의 축소 유형은 T의 키를 확장합니다. [중복]

Nov 21 2020

다음과 같은 인터페이스를 정의하려고합니다.

  • 하나의 속성은 일반 유형의 키입니다.
  • 다른 속성은 다른 속성의 해당 키와 연결된 유형에 의존 합니다.

내가 얻을 수있는 가장 가까운 것은 Typescript가 T [K]를 T의 모든 값의 공용체 유형으로 해석하는 것입니다. 그러나 K가 알려진 문자열 리터럴이면 더 좁힐 수있는 방법이있는 것 같습니다.

다음은 제가하려는 작업의 예입니다.

테스트

interface Person {
    age: number;
    name: string;
}

interface ColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T, keyof T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // ideally value should be "number" here, but it is "string|number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // ideally value should be "string" here, but it is "string|number"
            }
        },
    ]
}

답변

1 CraigC Nov 21 2020 at 03:20

선장 요사 리안의 관련 질문에 따라이 답변을 사용하여 유형을 좁힐 수있었습니다 .

다른 사람에게 도움이되는 경우를 대비하여 예제 사례에 적용한 방법입니다.

interface Person {
    age: number;
    name: string;
}

type ColumnDef<T> = {
    [K in keyof T]-?: BaseColumnDef<T, K>
  }[keyof T]


interface BaseColumnDef<T, K extends keyof T> {
    key: K;
    renderData: (value: T[K]) => void;
}

interface Report<T> {
    columns: ColumnDef<T>[];
}

const report: Report<Person> = {
    columns: [
        {
            key: "age", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "number"
            }
        },
        {
            key: "name", // this is correctly typed to be "age"|"name"
            renderData: (value) => {
                // value is now type "string"
            }
        },
    ]
}