我有一个函数logNumbers
,它接受一个字典,其中所有键都是字符串,所有值都是数字。我想用对象属于更严格的接口来调用logNumbers
,但仍然满足那些条件。
interface NumberDictionary {
[key: string]: number;
}
interface StatisticsResult {
mean: number;
mode: number;
median: number;
}
function logNumbers(numDict: NumberDictionary) { ... }
const results: StatisticsResult = {
mean: 1,
mode: 2,
median: 2,
};
//
// Error:
// Argument of type 'StatisticsResult' is not assignable to parameter of type 'NumberDictionary'.
// Index signature is missing in type 'StatisticsResult'.
//
logNumbers(results);
我希望StatisticsResult
保持不变,并以某种方式修改logNumbers
的签名。有没有办法做到这一点?也许我可以向打字稿发信号说,numDict
内不会向logNumbers
添加任何新键?
答案 0 :(得分:3)
如果您的目标是将函数限制为仅具有数字属性的对象,则可以将通用类型参数限制为仅具有数字的记录。
interface StatisticsResult {
mean: number;
mode: number;
median: number;
}
function logNumbers<T extends Record<keyof T, number>>(num: T) {
// Log the numbers as a table or something
}
const results: StatisticsResult = {
mean: 1,
mode: 2,
median: 2,
};
//ok
logNumbers(results);
答案 1 :(得分:0)
您在这里要做的只是:
interface StatisticsResult extends NumberDictionary {
mean: number;
mode: number;
median: number;
}
,现在StatisticsResult
将使用您定义的索引签名。 TypeScript不在乎您添加新键,而只是在乎您要将具有索引签名的类型分配给没有索引的类型。
您也可以强制转换为results
,尽管这样做比较棘手,因为您需要首先强制转换为unknown
(如果不强制转换,ts会抱怨您的类型没有任何重叠由于索引的标志性差异)和失败的目的:
logNumbers((results as unknown) as NumberDictionary);
最后,尽管您说过您不想更改StatisticalResult
,但您也可以在其中定义索引签名(据我所知,这样做也违背了使用NumberDictionary
类型的目的:< / p>
interface StatisticsResult{
[key: string]: number;
mean: number;
mode: number;
median: number;
}