TypeScript에 대한 주석:매핑 유형 및 찾기 유형

28369 단어 typestypescript

소개하다.
이러한 주석은 이해TypeScript에 도움이 될 뿐만 아니라, 특정 상황에서 TypeScript를 어떻게 활용하는지 찾아야 할 때 도움이 될 수 있다.모든 예는 TypeScript 3.2를 기반으로 합니다.

맵 유형
"TypeScript에 대한 주석"시리즈의 이 부분에서 TypeScript에서 유형 수준의 프로그래밍 지식을 향상시키고 싶습니다.이 주제를 근본적으로 이해하기 위해 우리는 그 중에서 토론한 몇 가지 주제를 되돌아보고 이러한 유형이 어떻게 실현되는지 더욱 깊이 이해할 것이다.더 구체적으로 말하면, 우리는 비추는 유형을 더욱 잘 이해할 수 있다.
하나의 예시에서, 우리는 하나의 Partial, 하나의 Required, 그리고 하나의 ReadOnly 유형을 실현했다.
type User = {
  id: number;
  name: string;
};

type MakeReadOnly<Type> = {readonly [key in keyof Type ]: Type[key]};
// Test MakeReadOnly
type ReadOnlyUser =  MakeReadOnly<User>;

/*
type ReadOnlyUser = {
  readonly id: number;
  readonly name: string;
}
*/
우리는 이러한 유형을 실현했지만 실제의 밑바닥 메커니즘을 더욱 깊이 토론하지 않았기 때문에 우리는 지금 이렇게 할 것이다.우리 MakeReadOnly 를 보십시오. 우리는 속성 형식을 비추어 새로운 형식을 만들 수 있음을 알았습니다.위의 특정 예에서 우리는 모든 속성 유형을 비추어 그것들을 읽기 전용으로 변환했다.
이전에 실현된 또 다른 예시를 봅시다.
type MakePick<Type, Keys extends keyof Type> = { [Key in Keys]: Type[Key] };
저희 MakePick 는 제공된 Pick 를 반영합니다. 모든 확장된 키 Type 를 훑어보고 새로운 형식의 키를 되돌려줍니다.
type User = {
  id: number;
  name: string;
  points: number;
};
type TestMakePick = MakePick<User, "id" | "name">;

/*
type TestMakePick = {
  id: number;
  name: string;
};
*/
이것이 바로 우리가 User에서 id와 이름을 선택하려고 했을 때 실제 발생한 상황입니다.
type TestMakePick = { [Key in "id" | "name"]: User[Key] };

/*
type TestMakePick = {
  id: number;
  name: string;
};
*/
찾기 유형(다음 단원에서는 자세히 살펴보겠습니다)을 사용하여 이러한 예제를 다음과 같이 재정의할 수 있습니다.
type TestMakePick = {
  id: User["id"],
  name: User["name"]
};

/*
type TestMakePick = {
  id: number;
  name: string;
};
*/
상술한 전환은 우리가 映射 유형의 작업 방식을 더욱 잘 이해하는 데 도움을 줄 것이다.

빠른 인코딩
더 높은 유형을 구축하기 위해 TypeScript 특성인 Lookup types와 keyof 두 가지를 살펴보겠습니다.
type UserKeyTypes = User["id" | "name" | "points"];

/*
type UserKeyTypes = number | string;
*/
keyof를 사용하여 다음과 같은 유형을 재작성할 수 있습니다.
type UserKeyTypes = User[keyof User];

/*
type UserKeyTypes = number | string;
*/
keyof는 TypeScript에서 키를 제공하지 않고 모든 키를 수동으로 정의하는 것을 피하는 데 도움을 줄 수 있으며, 이러한 유형이 변경될 때 계속 업데이트해야 하는 것을 피하는 데 도움이 된다.
type UserKeys = keyof User;

/*
type UserKeys = "id" | "name" | "string";
*/
색인 접근 형식 (색인 접근 형식) 을 찾으면 제공된 키의 형식에 접근할 수 있습니다.대상 속성에 접근하는 방법과 유사하지만 형식에 대해서는
type UserNameType = User["name"];

/*
type UserNameType = string;
*/
또한 이 섹션의 첫 번째 예제에서 설명한 것처럼 키를 찾을 수도 있습니다.
type UserKeyTypes = User["id" | "name" | "points"];

/*
type UserKeyTypes = number | string;
*/
이것은 개발자가 대상의 속성을 처리할 때 더욱 명확한 유형 처리를 제공할 수 있도록 흥미로운 특성이다.Ramda 라이브러리에서 prop 함수와 assoc 함수를 복제해서 더욱 간단하게 (sans currying) 실현합시다.
function prop(obj, key) {
  return obj[key]
}
prop 함수를 입력하는 방법 중 하나는 대상 형식을 제공하고 키를 문자열로 정의하는 것이다.그러나 TypeScript에서는 반환 유형을 추정할 수 없습니다.
키 형식을 더욱 명확하게 설명해야 합니다. 정의Key extends keyof Type를 통해 키 형식이 제공하는 대상 키 형식을 확장하여 이를 실현할 수 있습니다.
function prop<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key];
}

const user: User = {
  id: 1,
  name: "Test User",
  points: 0
};

const userName = prop(user, "name"); // const userName : string;
흥미로운 점은 TypeScript에서 반환 값의 반환 유형을 추정할 수 있다는 점입니다.
return obj[key]; // => Type[Key]
검색 유형과 키 of를 이용한 또 다른 장점은 기존의 속성 키만 전달할 수 있다는 것이다. prop
// The following will result in TypeScript complaining:
const userName = prop(user, "status");
// Argument of type '"status"' is not assignable to parameter of type '"id" | "name" | "points"'
따라서 존재하지 않는 속성에 액세스하려고 하면 TypeScript에서 제공하는 유형이 할당되지 않는다고 불평합니다.지금까지 배운 내용을 더 많이 이해하고 검증하기 위해 실시assoc하겠습니다.
function assoc<Type, Key extends keyof Type>(
  obj: Type,
  key: Key,
  value: Type[Key]
) {
  return { ...obj, [key]: value };
}
assocprop 함수와 유사해 보이지만 이번에도 값을 제공했기 때문에 Type[Key] 검색 형식을 사용하여 원하는 값 유형을 정의할 수 있습니다.
const updatedUserName = assoc(user, "name", "User Test A");
const updatedUserPoints = assoc(user, "points", 0);

// The following will examples result in TypeScript complaining:

const updatedUserPoint = assoc(user, "point", 0);
// Argument of type '"point"' is not assignable to parameter of type '"id" | "name" | "points"'

const updatedUserPointsAsString = assoc(user, "point", "0");
// Argument of type '"0"' is not assignable to parameter of type 'number'
검색 유형을 이용하여 우리는 예상된 업데이트 값이 정확한 유형을 가지고 있음을 보장할 수 있다.

매핑 유형 및 찾기 유형
마지막으로, 우리가 사용할 때 세운 더욱 높은 예시를 되돌아봅시다.
type RemoveUndefinable<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
}[keyof Type];

type RemoveNullableProperties<Type> = {
  [Key in RemoveUndefinable<Type>]: Type[Key]
};

type TestRemoveNullableProperties = RemoveNullableProperties<{
  id: number;
  name: string;
  property?: string;
}>;

/*
type TestRemoveNullableProperties = {
  id: number;
  name: string;
};
*/
RemoveNullableProperties 조건 형식은 하나의 형식이 필요하며, 비울 수 없는 속성 형식만 포함하는 새로운 형식을 되돌려줍니다.기존의 실현을 여러 부분으로 분해하는 것은 좋은 생각이다. 왜냐하면 우리는 현재 비추기와 검색 유형에 대해 더 잘 이해했기 때문이다.
type RemoveUndefinable<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
}[keyof Type];
먼저 RemoveUndefinable부터 시작하겠습니다.
type RemoveUndefinableKeys<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
};

type TestRemoveUndefinableKeys = RemoveUndefinable<{
  id: number;
  name: string;
  property?: string;
}>;

/*
type TestRemoveUndefinableKeys = {
  id: "id";
  name: "name";
  property?: undefined;
}
*/
키 이름이나 정의되지 않은 새로운 형식을 가져왔습니다. 이 형식이 정의되지 않은 형식으로 확장되었는지 여부에 따라 달라집니다.만약 기억하고 있다면, 우리는 이렇게 여러 종류를 찾을 수 있습니다. {a: number; b: string; c: number[]}["a" | "b"] 이것은 다음 단계에서 검색을 사용하여 제공된 종류의 모든 관련 키를 추출할 수 있음을 의미합니다.
type RemoveUndefinableKeys<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
};

type RemoveUndefinable<Type> = RemoveUndefinableKeys<Type>[keyof Type];

type TestRemoveUndefinable = RemoveUndefinable<{
  id: number;
  name: string;
  property?: string;
}>;

/*
type TestRemoveUndefinable = "id" | "name" | undefined;
*/
RemoveUndefinable 모든 맵의 키 이름을 되돌려줍니다. 따라서 다음 단계는 제공된 형식에서 존재하지 않는 키를 삭제합니다.
type RemoveUndefinableKeys<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
};

type RemoveUndefinable<Type> = RemoveUndefinableKeys<Type>[keyof Type]>;

type RemoveNullableProperties<Type> = {
  [Key in RemoveUndefinable<Type>]: Type[Key]
};

type TestRemoveNullableProperties = RemoveNullableProperties<{
  id: number;
  name: string;
  property?: string;
}>;

/*
type TestRemoveNullableProperties = {
  id: number;
  name: string;
};
*/
우리는 RemoveNullableProperties와 제공된 Pick 유형을 교환할 수 있다. Pick의 실현은 RemoveNullableProperties의 실현과 유사하기 때문이다.
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}
RemoveNullablePropertiesPick를 교환하면 다음과 같은 기능을 사용할 수 있습니다.
type RemoveUndefinableKeys<Type> = {
  [Key in keyof Type]: undefined extends Type[Key] ? never : Key
};

type RemoveNullableProperties<Type> = Pick<
  Type,
  RemoveUndefinableKeys<Type>[keyof Type]
>;

type TestRemoveNullableProperties = RemoveNullableProperties<{
  id: number;
  name: string;
  property?: string;
}>;

/*
type TestRemoveNullableProperties = {
  id: number;
  name: string;
};
*/
매핑 유형, 검색 유형, 키 of, TypeScript를 사용할 때 어떻게 활용하는지 잘 이해해야 한다.이 글에서 얻은 지식은 우리가 다가올'TypeScript 주석'에서 더욱 높은 유형 프로그래밍의 예시를 구축하는 데 도움이 될 것이다. 이 주석은 더욱 높은 유형 프로그래밍에 중심을 둘 것이다.

링크
TypeScript 2.1 Release notes
TypeScript 2.1: Mapped Types
TypeScript 2.1: keyof and Lookup Types
질문이나 피드백이 있으면 여기에 메시지를 남기거나 트위터를 통해 연결하십시오.

좋은 웹페이지 즐겨찾기