Typescript: λ°°μ—΄μ˜ κ°’μ—μ„œ μœ ν˜• λ§Œλ“€κΈ°

에 λ§Œλ“  2018λ…„ 10μ›” 22일  Β·  16μ½”λ©˜νŠΈ  Β·  좜처: microsoft/TypeScript


TypeScript 버전 : 3.0.3


검색어 : λ°°μ—΄μ˜ 값을 기반으둜 μž…λ ₯

λ°°μ—΄μ˜ λ¬Έμžμ—΄μ—μ„œ μœ ν˜•μ„ λ§Œλ“œλŠ” ν˜„μž¬ λ˜λŠ” κ³„νšλœ κΈ°λŠ₯이 μžˆμŠ΅λ‹ˆκΉŒ?

μ•”ν˜Έ

const values = ['A', 'B']
type Foo = OneOf<values> // Is there a way of doing this?

const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values

keyof μž‘λ™ 방식과 μœ μ‚¬ν•©λ‹ˆλ‹€.

const values = {
  A: 'A',
  B: 'B'
}
type Foo = keyof typeof values
const v1: Foo = 'A'
const v2: Foo = 'D' // Type '"D"' is not assignable to type '"A" | "B"'

κ΄€λ ¨ 문제:https://github.com/Microsoft/TypeScript/issues/20965

놀이터 링크 http://www.typescriptlang.org/play/#src = let % 20vals1 % 20 % 3D % 20 % 5B'A '% 2C % 20'B'% 5D % 0D % 0Atype % 20Foo1 % 20 % 3D % 20OneOf % 3Cvals1 % 3E % 20 % 2F % 2F % 20Is % 20there % 20a % 20way % 20of % 20doing % 20this % 3F % 0D % 0A % 0D % 0Alet % 20v1 % 3A % 20Foo1 % 20 % 3D % 20 ' A '% 20 % 2F % 2F % 20This % 20should % 20work % 0D % 0Alet % 20v2 % 3A % 20Foo1 % 20 % 3D % 20'D'% 20 % 2F % 2F % 20This % 20should % 20give % 20me % 20an % 20error % 20since % 20'D '% 20doesn't % 20exist % 20in % 20values ​​% 0D % 0A % 0D % 0Alet % 20vals2 % 20 % 3D % 20 % 7B % 0D % 0A % 20 % 20A % 3A % 20'A '% 2C % 0D % 0A % 20 % 20B % 3A % 20'B'% 0D % 0A % 7D % 0D % 0Atype % 20Foo2 % 20 % 3D % 20keyof % 20typeof % 20vals2 % 0D % 0Alet % 20v3 % 3A % 20Foo2 % 20 % 3D % 20'A '% 0D % 0Alet % 20v4 % 3A % 20Foo2 % 20 % 3D % 20'D'% 20 % 2F % 2F % 20Type % 20 '% 22D % 22'% 20is % 20not % 20assignable % 20to % 20type % 20 '% 22A % 22 % 20 % 7C % 20 % 22B % 22'

Question

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

λͺ¨λ“  16 λŒ“κΈ€

keyof λŠ” 컴파일 νƒ€μž„μ— μ •μ μœΌλ‘œ μ•Œλ €μ§„ 정보λ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μž‘λ™ν•©λ‹ˆλ‹€. TS의 μœ ν˜•μ€ μ™„μ „νžˆ μ§€μšΈ 수 있고 트랜슀 파일 된 μ½”λ“œμ— μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ λ°°μ—΄μ˜ λŸ°νƒ€μž„ μ½˜ν…μΈ λ₯Ό 기반으둜 μœ ν˜•μ„ λ§Œλ“œλŠ” 것이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.

이것은 κ°€λŠ₯ν•˜λ‹€:

function stringLiterals<T extends string>(...args: T[]): T[] { return args; }
type ElementType<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType> ? ElementType : never;

const values = stringLiterals('A', 'B');
type Foo = ElementType<typeof values>;

const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values

κ·Έλž˜λ„ 이것을 μˆ˜ν–‰ν•˜λŠ” 방법이 λͺ…ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. # 27179 κ΄€λ ¨μž…λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ—¬μ „νžˆ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μ •μ μœΌλ‘œ μ•Œλ €μ§„ 정보λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. κ·Έ μ‹œμ μ—μ„œ λ‚˜λŠ” 단지 ”A” | β€œB” 라고 λ§ν•˜λŠ” 것보닀 이점이 무엇인지 μ΄ν•΄ν•˜μ§€ λͺ»ν•©λ‹ˆλ‹€.

@fatcerberus λ°˜λ³΅λ˜λŠ” 정보λ₯Ό ν”Όν•˜λŠ” 것이 μœ μš©ν•©λ‹ˆλ‹€. const values = ["A", "B"]; type Foo = "A" | "B"; μ“°λ©΄ λ‹€λ₯Έ μ‚¬λžŒμ΄ λ‹€λ₯Έ μ‚¬λžŒμ„ λ³€κ²½ν•˜λŠ” 것을 μžŠμœΌλ©΄μ„œ κ·Έ 쀑 ν•˜λ‚˜λ₯Ό λ³€κ²½ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€. 당신은 μ“Έ 수 const values: Foo[] =["A", "B"]; ,ν•˜μ§€λ§Œ μ—¬μ „νžˆμ— μΆ”κ°€ ν•­λͺ©μ„ μΆ”κ°€ν•˜λŠ” κ°μˆ˜μ„±μ˜ Foo 와에 λ„£μ–΄ μžŠμ–΄ values .

μ§€κΈˆ μš°λ¦¬λŠ” 어디에 μžˆμŠ΅λ‹ˆκΉŒ?

@ andy-msκ°€ λ§ν–ˆλ“―μ΄ μˆ˜λ™μœΌλ‘œ 정보λ₯Ό λ°˜λ³΅ν•˜μ§€ μ•ŠλŠ” 것이 정말 유용 ν•  것이라고 λ§ν–ˆμŠ΅λ‹ˆλ‹€.
@fatcerberusκ°€ λ§ν–ˆλ“―μ΄ μœ ν˜•μ€ μ™„μ „νžˆ μ§€μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μˆœμˆ˜ν•˜μ§€ μ•Šμ€ λΆ€λΆ„ (예 : μ›Ή μ„œλΉ„μŠ€ λ˜λŠ” μ‚¬μš©μž)μ—μ„œ 얻은 데이터λ₯Ό λŸ°νƒ€μž„ ν™•μΈν•΄μ•Όν•˜λŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€.

@ andy-ms의 닡변을 기반 μœΌλ‘œν•˜κ³  typescript 3.4에 λ„μž… 된 const μ–΄μ„€ μ…˜μ„ μ‚¬μš©ν•˜λ©΄ 이제 λ‹€μŒκ³Ό 같은 μž‘μ—…μ„ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const values = ['A', 'B'] as const
type ElementType < T extends ReadonlyArray < unknown > > = T extends ReadonlyArray<
  infer ElementType
>
  ? ElementType
  : never

type Foo = ElementType<typeof values> // this is correctly inferred as literal "A" | "B"

이 λ¬Έμ œλŠ” '질문'으둜 ν‘œμ‹œλ˜μ—ˆμœΌλ©° 졜근 ν™œλ™μ΄ μ—†μŠ΅λ‹ˆλ‹€. μ²­μ†Œλ₯Ό μœ„ν•΄ μžλ™μœΌλ‘œ λ‹«ν˜”μŠ΅λ‹ˆλ‹€. μ—¬μ „νžˆ 응닡을 기닀리고 μžˆλ‹€λ©΄ μ§ˆλ¬Έμ€ 일반적으둜 stackoverflow에 더 μ ν•©ν•©λ‹ˆλ‹€.

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

λŒ€μ‹  :

export const items = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof items[number];
}

λ‹€μŒκ³Ό 같이 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

export const items = [
  'room',
  'room_with_gifter',
  'user_send'
] as const;

export type Item = typeof items;

export interface Activity {
  id?: string;
  type: Item;
}

image

_ type λ₯Ό λ³€μˆ˜ μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•˜λŠ” 것을 정말 μ‹«μ–΄ν•©λ‹ˆλ‹€ ._

@ 7kms

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

이제 μˆ˜μ—…μ—μ΄κ²Œ 있으면 μ–΄λ–‘ν•˜μ£ ?

class Class {
  const list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 const withType: typeof list[number];
}

μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. this.list[number] 도 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚΄ νŠΉμ •
μ‚¬μš© 사둀, list 을 static μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

@ 7kms

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

이제 μˆ˜μ—…μ—μ΄κ²Œ 있으면 μ–΄λ–‘ν•˜μ£ ?

class Class {
  const list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 const withType: typeof list[number];
}

μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. this.list[number] 도 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚΄ νŠΉμ •
μ‚¬μš© 사둀, list 을 static μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

당신은 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€ @vegerot const 직접 λ²”μœ„μ— class ꡬ문이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ κ·Έλž˜μ„œ.

@ 7kms

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

이제 μˆ˜μ—…μ—μ΄κ²Œ 있으면 μ–΄λ–‘ν•˜μ£ ?

class Class {
  const list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 const withType: typeof list[number];
}

μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. this.list[number] 도 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚΄ νŠΉμ •
μ‚¬μš© 사둀, list 을 static μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

당신은 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€ @vegerot const 직접 λ²”μœ„μ— class ꡬ문이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ κ·Έλž˜μ„œ.

@ 7kms λ‚΄ λ‚˜μœ. λ„ˆλ¬΄ 많이 λ³΅μ‚¬ν•΄μ„œ λΆ™μ—¬ λ„£μ—ˆμŠ΅λ‹ˆλ‹€. λ‚΄κ°€ λ§ν•˜λ €λŠ” 것은

class Class {
  private list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 private withType: typeof list[number];

// OR
  private withType2: typeof this.list[number];

}

λ“± λͺ¨λ‘ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
λ˜ν•œ νŠΉμ • μ‚¬μš© μ‚¬λ‘€μ—μ„œλŠ” λͺ©λ‘μ„ μ •μ μœΌλ‘œ μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

@ 7kms

[email protected] 이상. μ΄λ ‡κ²Œ ν•΄κ²°ν•΄

export const type = <const>[
  'room',
  'room_with_gifter',
  'user_send'
];

export interface Activity {
  id?: string;
  type: typeof type[number];
}

이제 μˆ˜μ—…μ—μ΄κ²Œ 있으면 μ–΄λ–‘ν•˜μ£ ?

class Class {
  const list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 const withType: typeof list[number];
}

μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. this.list[number] 도 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚΄ νŠΉμ •
μ‚¬μš© 사둀, list 을 static μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

당신은 μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€ @vegerot const 직접 λ²”μœ„μ— class ꡬ문이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ κ·Έλž˜μ„œ.

@ 7kms λ‚΄ λ‚˜μœ. λ„ˆλ¬΄ 많이 λ³΅μ‚¬ν•΄μ„œ λΆ™μ—¬ λ„£μ—ˆμŠ΅λ‹ˆλ‹€. λ‚΄κ°€ λ§ν•˜λ €λŠ” 것은

class Class {
  private list = <const>[
   'room',
   'room_with_gifter',
   'user_send'
 ];

 private withType: typeof list[number];

// OR
  private withType2: typeof this.list[number];

}

λ“± λͺ¨λ‘ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
λ˜ν•œ νŠΉμ • μ‚¬μš© μ‚¬λ‘€μ—μ„œλŠ” λͺ©λ‘μ„ μ •μ μœΌλ‘œ μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

class Class {
  private list = [
    "room",
    "room_with_gifter",
    "user_send"
  ] as const

  private withType: Class["list"][number]
}

@vegerot μ–΄λ•Œμš”?

@eyalch ꡉμž₯ν•©λ‹ˆλ‹€! κ°μ‚¬ν•©λ‹ˆλ‹€. λ‚˜λŠ” 해결책이 typeof λ˜λŠ” 무언가λ₯Ό 포함 ν•  것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. 이것이 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€μ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ…을 μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ, μ•„λ‹ˆλ©΄ 이것이 λ…Όμ˜λ˜λŠ” ν•Έλ“œλΆμœΌλ‘œ μ €λ₯Ό μ—°κ²°ν•΄ μ£Όκ² μŠ΅λ‹ˆκΉŒ?

@eyalch ꡉμž₯ν•©λ‹ˆλ‹€! κ°μ‚¬ν•©λ‹ˆλ‹€. λ‚˜λŠ” 해결책이 typeof λ˜λŠ” 무언가λ₯Ό 포함 ν•  것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. 이것이 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€μ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ…을 μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ, μ•„λ‹ˆλ©΄ 이것이 λ…Όμ˜λ˜λŠ” ν•Έλ“œλΆμœΌλ‘œ μ €λ₯Ό μ—°κ²°ν•΄ μ£Όκ² μŠ΅λ‹ˆκΉŒ?

@vegerot λ¬Όλ‘ μž…λ‹ˆλ‹€. "인덱슀 μœ ν˜•"이라고 μƒκ°ν•©λ‹ˆλ‹€. μ—¬κΈ° ν•Έλ“œλΆμ— μžˆμŠ΅λ‹ˆλ‹€ : https://www.typescriptlang.org/docs/handbook/advanced-types.html#index -types

도와 λ“œλ¦΄ μˆ˜μžˆμ–΄μ„œ κΈ°μ©λ‹ˆλ‹€!

% username % λ‹˜, ElementType μ†”λ£¨μ…˜μ΄ λ‹Ήμ‹ μ—κ²Œλ„ νš¨κ³Όκ°€ μ—†λ‹€λ©΄,
λ°°μ—΄ ν›„ as const μ—μ£Όμ˜ν•˜μ‹­μ‹œμ˜€. μ€‘μš”ν•˜λ‹€

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰