업데이트 된 답변 : 교차로 유형 추가 이후 &
두 개의 추론 된 유형을 즉석에서 "병합"할 수 있습니다.
다음은 일부 객체의 속성을 읽고 객체 from
위에 복사 하는 일반 도우미입니다 onto
. 동일한 객체를 반환 onto
하지만 두 속성 집합을 모두 포함하는 새 유형을 사용하여 런타임 동작을 올바르게 설명합니다.
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
이 저수준 도우미는 여전히 유형 어설 션을 수행하지만 설계 상 유형 안전합니다. 이 도우미를 사용하면 전체 형식 안전성으로 OP의 문제를 해결하는 데 사용할 수있는 연산자가 있습니다.
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
TypeScript 플레이 그라운드에서 사용해 보려면 여기를 클릭하십시오 . foo
유형 Foo
이되도록 제한 했으므로의 결과 merge
는 완전해야 Foo
합니다. 따라서로 이름 bar
을 바꾸면 bad
유형 오류가 발생합니다.
NB 그러나 여기에는 여전히 하나의 유형 구멍이 있습니다. TypeScript는 유형 매개 변수를 "함수가 아님"으로 제한하는 방법을 제공하지 않습니다. 따라서 혼란스럽고 함수를에 두 번째 인수로 전달할 수 있으며 merge
작동하지 않습니다. 따라서 이것이 선언 될 수있을 때까지 런타임에 포착해야합니다.
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };
.