키 및 관련 값 유형을 일반에 전달하여 인덱싱 된 유형을 좁 힙니다.

Takesi Tokugawa YD

유사한 질문과의 차이점

불행히도 TypeScript 제네릭 에 대한 암시 적 키 및 값 유형 관계 전달 질문에 대한 훌륭한 답변 은 현재 질문의 문제를 다루지 않습니다. generateInputsAccessObject해당 질문의 대상 함수 인에서는 하위 유형 종속 속성을 사용하지 않습니다.

실제로 위의 질문은 암시 적 키와 값 유형 관계를 제목 인 TypeScript 제네릭에 전달하지 않고 해결되었지만 이제 더 이상 피할 수 없다고 생각합니다.

표적

다음 과 같은 EntitySpecification일반 유형 인을 작성하십시오 ProductSpecification.

  1. properties의 유형은 색인화되지 않아야합니다 . 그것은 타이프 라이터 컴파일러는 무엇을 알고 있어야한다는 것을 의미 IDprice존재하지 않는 - 존재하지만, 다른 키가.
  2. properties반복 가능 Object.entires("ProductSpecification.properties")해야합니다 (작동해야 함).
  3. ID그리고 price다른 유형을 가질 수 있지만, 우리가 호출 할 때 EntitySpecification.properties.IDEntitySpecification.properties.price, 타이프 라이터 컴파일러는 유형을 알고 있어야합니다.

export type Product = {
  ID: string;
  price: number;
};

const ProductSpecification: EntitySpecification<keyof Product> = {
  name: "Product",
  properties: {
    ID: {
      type: DataTypes.string,
      emptyStringIsAllowed: false
    },
    price: {
      type: DataTypes.number,
      numberSet: NumbersSets.nonNegativeInteger
    }
  }
};

여기:

export enum DataTypes {
  number = "NUMBER",
  string = "STRING"
}


export enum NumbersSets {
  naturalNumber = "NATURAL_NUMBER",
  nonNegativeInteger = "NON_NEGATIVE_INTEGER",
  negativeInteger = "NEGATIVE_INTEGER",
  negativeIntegerOrZero = "NEGATIVE_INTEGER_OR_ZERO",
  anyInteger = "ANY_INTEGER",
  positiveDecimalFraction = "POSITIVE_DECIMAL_FRACTION",
  negativeDecimalFraction = "NEGATIVE_DECIMAL_FRACTION",
  decimalFractionOfAnySign = "DECIMAL_FRACTION_OF_ANY_SIGN",
  anyRealNumber = "ANY_REAL_NUMBER"
}

export type StringSpecification = {
  readonly type: DataTypes.string;
  readonly emptyStringIsAllowed: boolean;
};

export type NumberSpecification = {
  readonly type: DataTypes.number;
  readonly numberSet: NumbersSets;
};

물론 EntitySpecification키를 미리 알지 못하지만 키 수는 임의적으로 클 수 있습니다 (현재의 경우 2가 아님 ProductSpecification).

지금은 내 최고

아래 솔루션은 처음 두 목표를 충족합니다.

export type EntitySpecification<Keys extends string> = {
  readonly name: string;
  readonly properties: { [key in Keys]: StringSpecification | NumberSpecification };
};

여기 갈등 상황, 세 번째 조건 위반의 결과 :

type StringValidationRules = {
  emptyStringIsAllowed: boolean;
};

const ID_ValidationRules: StringValidationRules = {
  emptyStringIsAllowed: ProductSpecification__EXPERIMENTAL.properties.ID.emptyStringIsAllowed;
}

TypeScript IDStringSpecification유형 이있는 것을 모르기 때문에 다음과 같은 오류가 있습니다.

TS2339: Property 'emptyStringIsAllowed' does not exist on type 'StringSpecification | NumberSpecification'.   Property 'emptyStringIsAllowed' does not exist on type 'NumberSpecification'.
jcalz

객체 유형 EntitySpecification의 속성 키 유형 만 매핑하는 것처럼 보이지만 해당 값 유형매핑해야합니다 . 이 경우 키뿐만 아니라 전체 객체 유형을 전달하는 것이 가장 좋습니다. 그런 다음 일부 매핑 구조를 통해 속성 유형을 매핑 할 수 있으며 지금처럼 키 매핑을 계속할 수 있습니다.

다음은 필요한 매핑 구조를 나타내는 한 가지 방법입니다.

type DataMapping =
    { type: number, specification: NumberSpecification }
    | { type: string, specification: StringSpecification }

어디에서도 실제 유형 을 사용할 계획이 없습니다 DataMapping. 컴파일러가 속성 유형을 사양 인터페이스에 연결하는 데 사용할 수있는 유형 정의 일뿐입니다.

이제 EntitySpecification다음과 같이 정의 할 수 있습니다.

type EntitySpecification<T extends Record<keyof T, DataMapping["type"]>> = {
    readonly name: string;
    readonly properties: { [K in keyof T]: Extract<DataMapping, { type: T[K] }>['specification'] };
};

내가하고 있습니다 제약 T 그의 재산 유형에서 언급되는 객체 유형으로 type의 재산입니다 DataMapping. 이것은 Product누구의 속성 유형이 numberstring허용하지만 (현재) 해당 사양이 {oops: boolean}없기 때문에 같은 것을 허용 boolean하지 않습니다.

properties속성이있다 맵형 키가있는 K의 키와 동일한 T값을 가지는에서 해당 속성 타입으로부터 변환된다 (이전에 수행 된 바와 같이)와 TT[K].

특정 속성 매핑은입니다 Extract<DataMapping, {type: T[K]}>['specification']. Extract유틸리티 유형사용하여 속성이 DataMapping공용체 의 멤버를 선택한 다음 해당 멤버 에서 속성 을 반환합니다 .typeT[K]specification


그것이 어떻게 작동하는지 보자 Product:

type Product = {
    ID: string;
    price: number;
};

type ProductSpecification = EntitySpecification<Product>;
/* type ProductSpecification = {
    readonly name: string;
    readonly properties: {
        ID: StringSpecification;
        price: NumberSpecification;
    };
} */

그게 당신이 원했던 것 같아요. 당신이 값이있는 경우 p유형을 ProductSpecification다음 p.properties.ID형식이어야 StringSpecification하고, p.properties.price유형이어야합니다 NumberSpecification. 만세!


코드에 대한 플레이 그라운드 링크

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

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

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

일반 키 유형 및 중첩 된 일반 값 유형으로 Java 맵에 넣을 수 없습니다.

분류에서Dev

조건부 유형을 사용하여 팩토리 함수에서 반환 된 인스턴스 범위를 좁 힙니다.

분류에서Dev

개체 내에 이미 설정된 속성을 기반으로 공용체 유형을 좁 힙니다.

분류에서Dev

전달 된 가드 기능을 통해 일반 유형을 좁히는 방법은 무엇입니까?

분류에서Dev

프로토콜 및 관련 유형과 함께 일반 유형을 사용하십니까?

분류에서Dev

Typescript에서 인덱싱 된 유형에 유형 인수를 전달하는 방법은 무엇입니까?

분류에서Dev

유형 선언에서 정확한 현재 인덱싱 된 키를 얻을 수 있습니까?

분류에서Dev

매개 변수화 / 인덱싱 된 유형에서 catamorphism을 작동시키는 방법은 무엇입니까?

분류에서Dev

반환 값이 관련된 함수의 반환에 조건부 유형을 어떻게 추가합니까?

분류에서Dev

값이 해당 키의 반환 유형을 가진 함수 인 동안 인터페이스의 키로 객체를 인덱싱합니다.

분류에서Dev

BigQuery : 상관 된 하위 쿼리에서 레코드 유형의 고유 한 값을 반환해야합니다.

분류에서Dev

Typescript는 클래스 속성 (.filter, .find 등)에 따라 유형을 좁 힙니다.

분류에서Dev

Constexpr은 계층 적으로 관련된 두 유형 사이의 포인터 static_cast가 포인터 값을 변경하는지 확인합니다.

분류에서Dev

형식 주석을 사용하여 이미 선언 된 Python 변수의 형식을 좁 힙니다.

분류에서Dev

인터페이스에 대한 동적 ([키 : 유형] : 유형) 및 정적 유형을 혼합하는 방법

분류에서Dev

이 파일을 읽고 튜플 유형의 키와 float 유형의 값으로 사전을 만듭니다.

분류에서Dev

인덱싱 된 개체 (사전)의 값 형식에 일반적으로 액세스하도록 Typescript 인덱싱 된 개체 확장

분류에서Dev

TypeScript의 인덱스를 통해 액세스 한 일반 값 유형을 어떻게 전달합니까?

분류에서Dev

JMockit-기대 값은 개인 필드와 관련된 값 대신 이전 값을 반환합니다.

분류에서Dev

Perl 해시에서 키 및 관련 값을 삭제하는 데 문제가 있습니다.

분류에서Dev

Object.entries 유형을 유지하는 Typescript 키-값 관계

분류에서Dev

고유 한 "attendable_type"및 "attendable_id"를 사용하여 rails에서 다형성 테이블을 인덱싱하는 방법-Rails 4

분류에서Dev

Swift 3-런타임에서 해당 키 및 값 유형을 결정하는 방법은 무엇입니까?

분류에서Dev

객체 키 / 값에 여러 매핑 된 유형을 사용합니다. Union에서 하나의 값만 필요하십니까?

분류에서Dev

조인 및 관련 테이블의 열 이름과 값을 일치시키는 방법은 무엇입니까?

분류에서Dev

반응 형 디자인을 구현하고 크기를 조정하는 동안 배경 이미지와 관련된 버튼 및 물건의 위치를 유지하는 방법은 무엇입니까?

분류에서Dev

[]를 사용하여 인덱싱을 유형의 표현식에 적용 할 수 없습니다.

분류에서Dev

AltGr과 관련된 xmodmap 바인딩이 일부 키에서만 작동하는 이유는 무엇입니까?

분류에서Dev

AltGr과 관련된 xmodmap 바인딩이 일부 키에서만 작동하는 이유는 무엇입니까?

Related 관련 기사

  1. 1

    일반 키 유형 및 중첩 된 일반 값 유형으로 Java 맵에 넣을 수 없습니다.

  2. 2

    조건부 유형을 사용하여 팩토리 함수에서 반환 된 인스턴스 범위를 좁 힙니다.

  3. 3

    개체 내에 이미 설정된 속성을 기반으로 공용체 유형을 좁 힙니다.

  4. 4

    전달 된 가드 기능을 통해 일반 유형을 좁히는 방법은 무엇입니까?

  5. 5

    프로토콜 및 관련 유형과 함께 일반 유형을 사용하십니까?

  6. 6

    Typescript에서 인덱싱 된 유형에 유형 인수를 전달하는 방법은 무엇입니까?

  7. 7

    유형 선언에서 정확한 현재 인덱싱 된 키를 얻을 수 있습니까?

  8. 8

    매개 변수화 / 인덱싱 된 유형에서 catamorphism을 작동시키는 방법은 무엇입니까?

  9. 9

    반환 값이 관련된 함수의 반환에 조건부 유형을 어떻게 추가합니까?

  10. 10

    값이 해당 키의 반환 유형을 가진 함수 인 동안 인터페이스의 키로 객체를 인덱싱합니다.

  11. 11

    BigQuery : 상관 된 하위 쿼리에서 레코드 유형의 고유 한 값을 반환해야합니다.

  12. 12

    Typescript는 클래스 속성 (.filter, .find 등)에 따라 유형을 좁 힙니다.

  13. 13

    Constexpr은 계층 적으로 관련된 두 유형 사이의 포인터 static_cast가 포인터 값을 변경하는지 확인합니다.

  14. 14

    형식 주석을 사용하여 이미 선언 된 Python 변수의 형식을 좁 힙니다.

  15. 15

    인터페이스에 대한 동적 ([키 : 유형] : 유형) 및 정적 유형을 혼합하는 방법

  16. 16

    이 파일을 읽고 튜플 유형의 키와 float 유형의 값으로 사전을 만듭니다.

  17. 17

    인덱싱 된 개체 (사전)의 값 형식에 일반적으로 액세스하도록 Typescript 인덱싱 된 개체 확장

  18. 18

    TypeScript의 인덱스를 통해 액세스 한 일반 값 유형을 어떻게 전달합니까?

  19. 19

    JMockit-기대 값은 개인 필드와 관련된 값 대신 이전 값을 반환합니다.

  20. 20

    Perl 해시에서 키 및 관련 값을 삭제하는 데 문제가 있습니다.

  21. 21

    Object.entries 유형을 유지하는 Typescript 키-값 관계

  22. 22

    고유 한 "attendable_type"및 "attendable_id"를 사용하여 rails에서 다형성 테이블을 인덱싱하는 방법-Rails 4

  23. 23

    Swift 3-런타임에서 해당 키 및 값 유형을 결정하는 방법은 무엇입니까?

  24. 24

    객체 키 / 값에 여러 매핑 된 유형을 사용합니다. Union에서 하나의 값만 필요하십니까?

  25. 25

    조인 및 관련 테이블의 열 이름과 값을 일치시키는 방법은 무엇입니까?

  26. 26

    반응 형 디자인을 구현하고 크기를 조정하는 동안 배경 이미지와 관련된 버튼 및 물건의 위치를 유지하는 방법은 무엇입니까?

  27. 27

    []를 사용하여 인덱싱을 유형의 표현식에 적용 할 수 없습니다.

  28. 28

    AltGr과 관련된 xmodmap 바인딩이 일부 키에서만 작동하는 이유는 무엇입니까?

  29. 29

    AltGr과 관련된 xmodmap 바인딩이 일부 키에서만 작동하는 이유는 무엇입니까?

뜨겁다태그

보관