我希望修复 addRandomValue
函数的类型,以便 Typescript 编译器不允许下面的调用,因为 baz
不在 FooBar
中。
type WithRandomNumber<T> = T & { randomValue: number; };
function addRandomValue<T>(inputObj: T): WithRandomNumber<T> {
return {
...inputObj,
randomValue: Math.random(),
};
}
interface FooBar {
foo: string;
bar: number;
};
const resultObj: WithRandomNumber<FooBar> = addRandomValue({
foo: 'hello',
bar: 100,
baz: true,
});
也就是说,我想约束 T
的泛型 addRandomValue
(以及 inputObj
的类型),以便如果预期的返回类型是 WithRandomNumber<Foobar>
(因为这是我们将返回值分配给的变量类型),那么 T
必须等于 FooBar
。
答案 0 :(得分:1)
您不能强制编译器拒绝基于 LH 类型声明的赋值,而是必须在调用函数时传递泛型参数:
type WithRandomNumber<T> = T & { randomValue: number; };
function addRandomValue<T>(inputObj: T): WithRandomNumber<T> {
return {
...inputObj,
randomValue: Math.random(),
};
}
interface FooBar {
foo: string;
bar: number;
};
const resultObj = addRandomValue<FooBar>({
foo: 'hello',
bar: 100,
baz: true,
});
问题不在于编译器不够智能,而是与根据规范评估 Javascript 的方式有关。由于您没有在调用站点传递泛型参数,它推断类型 {foo: string bar: number, baz: boolean }
并评估 RH 表达式 then 它将结果分配给具有您声明的类型的 LH var。因为 TS 是结构类型的,它确实是一个有效的赋值,因为它具有 FooBar 所需的所有属性:
const foo = {
foo: 'hello',
bar: 100,
baz: true,
};
const bar: FooBar = foo;