업데이트 된 답변 : 교차로 유형 추가 이후 & 두 개의 추론 된 유형을 즉석에서 "병합"할 수 있습니다.
다음은 일부 객체의 속성을 읽고 객체 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 };.