Typescript TS索引类型-在接口中使用索引类型时,编译器无法解析精确值
如果我有以下功能:Typescript TS索引类型-在接口中使用索引类型时,编译器无法解析精确值,typescript,Typescript,如果我有以下功能: function test<T, K extends keyof T>(o: T, propertyValue: T[K], propertyName: K) { // ... do something } 编译器能够检测到模型属性不是字符串类型,所以测试调用行失败。但如果我尝试在如下界面中使用索引类型: export interface Change<T, K extends keyof T = keyof T> { timestamp
function test<T, K extends keyof T>(o: T, propertyValue: T[K], propertyName: K) {
// ... do something
}
编译器能够检测到模型属性不是字符串类型,所以测试调用行失败。但如果我尝试在如下界面中使用索引类型:
export interface Change<T, K extends keyof T = keyof T> {
timestamp: number;
field: K;
value: T[K];
}
const change: Change<Car> = {
timestamp: 1484684700749,
field: 'model',
value: 0
};
导出接口更改{
时间戳:数字;
字段:K;
值:T[K];
}
常量更改:更改={
时间戳:1484684700749,
字段:'模型',
数值:0
};
它编译得很好。它允许您将值设置为字符串或数字,即使字段指定了实际属性。我是做错了什么,还是因为编译器的工作原理,在这种情况下这是不可能的
您可以看到实际示例,这是因为
K
可以是T
的任意键,typescript无法知道是哪个键
考虑这个例子:
constmakechange=(args:any):Change=>{
//在这里返回更改的一些逻辑。
}
K
现在应该使用什么类型的Change
。由于字段
的值是在运行时确定的,因此在编译期间不能分配静态类型
解决此问题的方法是定义更改
类型,如下所示:
接口更改{
时间戳:数字;
字段:K;
值:T[K];
}
常量更改:更改={
时间戳:1484684700749,
字段:'模型',
值:0//未按预期工作。
};
您需要在类型中指定字段(通用参数K
),以便静态类型检查工作
如果在其他部分中使用Change
界面,但不使用特定字段,则始终可以向函数中添加泛型类型,如下所示:
const uploadChange=(change:change)=>{
// ...
}
我理解所有这些,但我想知道编译器是如何为我的函数示例进行分类的函数测试(o:T,propertyValue:T[K],propertyName:K){/..do something}测试(滑行,0,'model');//它检测到model属性应该是string而不是number```如果它在这里可以做到这一点,那么它为什么不能在接口示例中做到这一点。这有什么区别?因为对于接口,您有一个泛型类型,如果没有任何更高阶的推理就无法解决,并且在函数调用中,“model”
将用作编译时已知的狭窄类型。通过接口,类型声明let x:type
是完全独立的,必须在不初始化变量的情况下自行编译
export interface Change<T, K extends keyof T = keyof T> {
timestamp: number;
field: K;
value: T[K];
}
const change: Change<Car> = {
timestamp: 1484684700749,
field: 'model',
value: 0
};