단일 인수를 문자열로 받아들이고 일치하는 type
속성을 가진 객체를 반환하는 클래스 메서드가 있습니다. 이 메서드는 식별 된 공용체 형식을 축소하는 데 사용되며 반환 된 개체가 항상 type
구분 값을 갖는 특정 좁혀진 형식이어야합니다.TypeScript의 일반, 식별 된 공용체에서 반환 유형 좁히기
제네릭 매개 변수에서 형식을 정확하게 좁히는이 메서드에 대한 형식 시그니처를 제공하려하지만 사용자가 명시 적으로 범위를 좁혀야하는 형식화 된 유니온에서이를 구별하려고 시도하는 것은 아무것도 아닙니다. 아래로. 그건 효과가 있지만 성가시다.
는 희망이 최소 재생은 명확하게 :
interface Action {
type: string;
}
interface ExampleAction extends Action {
type: 'Example';
example: true;
}
interface AnotherAction extends Action {
type: 'Another';
another: true;
}
type MyActions = ExampleAction | AnotherAction;
declare class Example<T extends Action> {
// THIS IS THE METHOD IN QUESTION
doSomething<R extends T>(key: R['type']): R;
}
const items = new Example<MyActions>();
// result is guaranteed to be an ExampleAction
// but it is not inferred as such
const result1 = items.doSomething('Example');
// ts: Property 'example' does not exist on type 'AnotherAction'
console.log(result1.example);
/**
* If the dev provides the type more explicitly it narrows it
* but I'm hoping it can be inferred instead
*/
// this works, but is not ideal
const result2 = items.doSomething<ExampleAction>('Example');
// this also works, but is not ideal
const result3: ExampleAction = items.doSomething('Example');
가 나는 또한 동적으로 "매핑 유형"구축을 시도, 영리 점점 시도 - TS에서 상당히 새로운 기능입니다.
declare class Example2<T extends Action> {
doSomething<R extends T['type'], TypeMap extends { [K in T['type']]: T }>(key: R): TypeMap[R];
}
이 같은 결과를 앓고 : 그것은 때문에 형태 맵 { [K in T['type']]: T }
각 계산 된 재산, T
에 대한 값의 유형을 축소하지 않습니다는 K in
반복의 각 속성에 대해하지 입니다 대신하다 똑같은 MyActions
노동 조합. 사용자가 사용할 수있는 미리 정의 된 매핑 된 유형을 제공하도록 요구하는 경우 실제로 작동하지만 매우 실용적인 개발자 경험이 될 수 있으므로 옵션이 아닙니다. (노동 조합은 거대합니다)
이 사례는 이상하게 보일 수 있습니다. 내 문제를 더 소모적 인 형태로 추출하려했지만 실제로 사용 사례는 Observables에 관한 것입니다. 익숙하다면 ofType
operator provided by redux-observable을보다 정확하게 입력하려고합니다. 기본적으로 filter()
on the type
property의 약자입니다.
이것은 사실 Observable#filter
과 Array#filter
도 유형을 좁히는 것과 매우 유사하지만, 술어 콜백에 value is S
반환 값이 있기 때문에 TS가이를 파악한 것으로 보입니다. 여기서 내가 비슷한 것을 어떻게 적용 할 수 있는지는 명확하지 않다.
후손을 위해 내가 원하는 것은 실제로 TS에 의해 현재 지원되지 않습니다. https://github.com/Microsoft/TypeScript/issues/17915에 요청하는 기존 티켓이 있습니다. 실제로 유연하게 사용할 수 있는지는 잘 모르겠지만 가장 유연한 절충안을 제공합니다. – jayphelps
도 똑똑했다 af – jayphelps
'Unionize'이'T [keyof T]'가 아닌 이유는 무엇입니까? –
jcalz