programing

TypeScript에 keyof와 유사한 value of이 있습니까?

javamemo 2023. 3. 16. 21:06
반응형

TypeScript에 keyof와 유사한 value of이 있습니까?

입력으로 키와 값이 지정된 값에 객체 속성을 할당할 수 있으면서도 값의 유형을 결정할 수 있으면 합니다.설명하기가 어렵기 때문에 이 코드로 문제를 파악할 수 있습니다.

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: any로.value: valueof JWT하지만 소용없었어요

이상적으로.onChange('expire', 1337)실패하는 이유는1337날짜 유형이 아닙니다.

어떻게 하면 바꿀 수 있을까?value: any지정된 키의 값이 될 수 있습니까?

업데이트: 질문 제목이 가능한 모든 자산 가치 유형의 결합을 찾는 사람들을 끌어모으는 것 같습니다. 방법과 비슷합니다.keyof는 가능한 모든 속성 키 유형의 조합을 제공합니다.우선 그 사람들을 돕자.만들 수 있습니다.ValueOf와 비슷한.keyof인덱스 액세스유형을 사용하여keyof 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']; // look up a in Foo
type sameAsNumber = Foo['b']; // look up 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]필요한 색인화된 액세스 유형.

오브젝트의 유니언 타입을 추출하는 다른 방법이 있습니다.

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

결과:1 | "some_string"

아직 실장을 원하는 사람이 있는 경우valueof어떤 목적으로든 이건 내가 생각해낸 거야

type valueof<T> = T[keyof T]

사용방법:

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

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

아래 함수를 사용하면 특정 키에 대한 값으로 값을 제한할 수 있습니다.

function setAttribute<T extends Object, U extends keyof T>(obj: T, key: U, value: T[U]) {
    obj[key] = value;
}

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

const dog: Pet = { name: 'firulais', age: 8 };

setAttribute(dog, 'name', 'peluche')     <-- Works
setAttribute(dog, 'name', 100)           <-- Error (number is not string)
setAttribute(dog, 'age', 2)              <-- Works
setAttribute(dog, 'lastname', '')        <-- Error (lastname is not a property)

이것을 시험해 보세요.

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...']>

사용자 자신이 값의 유형을 가져오기 위해 Generic을 만들 수 있지만 개체 선언이 선언되어야 함을 고려하십시오.as const예를 들어 다음과 같습니다.

export const APP_ENTITIES = {
  person: 'PERSON',
  page: 'PAGE',
} as const; <--- this `as const` I meant

그러면 다음 범용이 올바르게 동작합니다.

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

이제 다음과 같이 사용하세요.

const entity: ValueOf<typeof APP_ENTITIES> = 'P...'; // ... means typing

   // it refers 'PAGE' and 'PERSON' to you

문제를 완벽하게 해결할 수 있는 기존 답변에 감사드립니다.이 일반적인 유틸리티 유형을 Import하고 싶다면 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>;

제네릭스의 도움을 받아T그것은 JWT의 핵심이며 유형화된 가치이다.JWT[T]

function onChange<T extends keyof JWT>(key: T, value: JWT[T]);

는 그 뒤에 이어지는 이다.obj[key] = value + ' (assigned)';는, 하려고 하기 하지 않습니다.string로로 합니다.string & Datekey로로 합니다.token이 '타깃 변수 타입'인 을 알 수 있습니다.string.

이 문제를 해결하는 또 다른 방법은 타입 가드를 사용하는 것입니다.

// IF we have such a guard defined
function isId(input: string): input is 'id' {
  if(input === 'id') {
    return true;
  }

  return false;
}

// THEN we could do an assignment in "if" block
// instead of switch and compiler knows obj[key] 
// expects string value
if(isId(key)) {
  obj[key] = value + ' (assigned)';
}

type-fest lib를 사용하면ValueOf다음과 같이 합니다.

import type { ValueOf } from 'type-fest';

export const PATH_NAMES = {
  home: '/',
  users: '/users',
  login: '/login',
  signup: '/signup',
};

interface IMenu {
  id: ValueOf<typeof PATH_NAMES>;
  label: string;
  onClick: () => void;
  icon: ReactNode;
}

  const menus: IMenu[] = [
    {
      id: PATH_NAMES.home,
      label: t('common:home'),
      onClick: () => dispatch(showHome()),
      icon: <GroupIcon />,
    },
    {
      id: PATH_NAMES.users,
      label: t('user:users'),
      onClick: () => dispatch(showUsers()),
      icon: <GroupIcon />,
    },
  ];

제가 해결책을 찾을 때마다 했던 말이 약간 주제에서 벗어났다는 걸 깨달았어요나는 이 직책으로 보내졌다.String Literal Type 제너레이터를 찾고 계신 분은 여기 있습니다.

그러면 개체 유형에서 문자열 리터럴 목록이 생성됩니다.

export type StringLiteralList<T, K extends keyof T> = T[keyof Pick<T, K>];

type DogNameType = { name: "Bob", breed: "Boxer" } | { name: "Pepper", breed: "Spaniel" } | { name: "Polly", breed: "Spaniel" };

export type DogNames = StringLiteralList<DogNameType, "name">;

// type DogNames = "Bob" | "Pepper" | "Polly";

원라이너:

type ValueTypesOfPropFromMyCoolType = MyCoolType[keyof MyCoolType];

일반적인 방법의 예:

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

언급URL : https://stackoverflow.com/questions/49285864/is-there-a-valueof-similar-to-keyof-in-typescript

반응형