[typescript] TypeScript의`keyof`와 유사한`valueof`가 있습니까?

입력으로 키와 값이 주어진 값에 개체 속성을 할당 할 수 있지만 여전히 값의 유형을 결정할 수 있기를 원합니다. 설명하기가 조금 어렵 기 때문에이 코드는 문제를 드러내야합니다.

type JWT = { id: string, token: string, expire: Date };
const obj: JWT = { id: 'abc123', token: 'tk01', expire: new Date(2018, 2, 14) };

function print(key: keyof JWT) {
    switch (key) {
        case 'id':
        case 'token':
            console.log(obj[key].toUpperCase());
            break;
        case 'expire':
            console.log(obj[key].toISOString());
            break;
    }
}

function onChange(key: keyof JWT, value: any) {
    switch (key) {
        case 'id':
        case 'token':
            obj[key] = value + ' (assigned)';
            break;
        case 'expire':
            obj[key] = value;
            break;
    }
}

print('id');
print('expire');
onChange('id', 'def456');
onChange('expire', new Date(2018, 3, 14));
print('id');
print('expire');

onChange('expire', 1337); // should fail here at compile time
print('expire'); // actually fails here at run time

나는 변화 시도 value: anyvalue: valueof JWT하지만, 작동하지 않았다.

이상적으로 는 날짜 유형이 아니기 onChange('expire', 1337)때문에 실패 1337합니다.

value: any주어진 키의 값으로 변경 하려면 어떻게 해야합니까?



답변

업데이트 : 질문 제목 keyof이 모든 가능한 속성 키 유형의 통합을 제공 하는 방식과 유사하게 모든 가능한 속성 값 유형의 통합을 찾는 사람들을 끌어들이는 것처럼 보입니다 . 먼저 그 사람들을 돕자. 다음 과 같이 키로 with 조회 유형 을 사용하여 와 ValueOf유사하게 만들 수 있습니다 .keyofkeyof T

type ValueOf<T> = T[keyof T];

당신에게주는

type Foo = { a: string, b: number };
type ValueOfFoo = ValueOf<Foo>; // string | number

언급 된 질문에 대해보다 좁은 개별 키를 사용 keyof T하여 관심있는 값 유형 만 추출 할 수 있습니다 .

type sameAsString = Foo['a']; // lookup a in Foo
type sameAsNumber = Foo['b']; // lookup b in Foo

키 / 값 쌍이 함수에서 제대로 “일치”하는지 확인하려면 다음과 같이 제네릭 과 조회 유형을 사용해야 합니다.

declare function onChange<K extends keyof JWT>(key: K, value: JWT[K]): void;
onChange('id', 'def456'); // okay
onChange('expire', new Date(2018, 3, 14)); // okay
onChange('expire', 1337); // error. 1337 not assignable to Date

아이디어는 key매개 변수를 통해 컴파일러가 일반 K매개 변수 를 추론 할 수 있다는 것입니다 . 그런 다음 필요한 조회 유형 인 value일치 JWT[K]가 필요합니다.

도움이되는 희망; 행운을 빕니다!


답변

누군가가 valueof어떤 목적 으로든 구현을 찾고 있다면 이것은 내가 생각해 낸 것입니다.

type valueof<T> = T[keyof T]

용법:

type actions = {
  a: {
    type: 'Reset'
    data: number
  }
  b: {
    type: 'Apply'
    data: string
  }
}
type actionValues = valueof<actions>

예상대로 작동합니다. 🙂 가능한 모든 유형의 Union을 반환합니다.


답변

객체의 공용체 유형을 추출하는 또 다른 방법이 있습니다.

  const myObj = { a: 1, b: 'some_string' } as const;
  type values = typeof myObj[keyof typeof myObj];

결과: 1 | "some_string"


답변

문제를 완벽하게 해결 한 기존 답변에 감사드립니다. 이 일반적인 것을 가져오고 싶다면 lib에이 유틸리티 유형이 포함되어 있습니다.

https://github.com/piotrwitek/utility-types#valuestypet

import { ValuesType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = ValuesType<Props>;


답변

이 시도:

type ValueOf<T> = T extends any[] ? T[number] : T[keyof T]

배열 또는 일반 개체에서 작동합니다.

// type TEST1 = boolean | 42 | "heyhey"
type TEST1 = ValueOf<{ foo: 42, sort: 'heyhey', bool: boolean }>
// type TEST2 = 1 | 4 | 9 | "zzz..."
type TEST2 = ValueOf<[1, 4, 9, 'zzz...']>


답변

짧막 한 농담:

type ValueTypesOfPropFromMyCoolType = MyCoolType[keyof MyCoolType];

일반 메소드의 예 :

declare function doStuff<V extends MyCoolType[keyof MyCoolType]>(propertyName: keyof MyCoolType, value: V) => void;


답변