Typescript:基于预期返回类型约束函数泛型类型



我希望修复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,
});

也就是说,我想约束addRandomValue的通用T(因此inputObj的类型),因此,如果预期的返回类型是WithRandomNumber<Foobar>(因为这是我们分配返回值的变量类型),那么T必须等于FooBar

您不能强迫编译器阻止基于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表达式然后它将结果分配给具有您声明的类型的LH变量。因为TS是结构类型的,这确实是一个有效的赋值,因为它具有FooBar所需的所有属性:

const foo = {
foo: 'hello',
bar: 100,
baz: true,
};
const bar: FooBar = foo;

游乐场

相关内容

  • 没有找到相关文章