Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript TS索引类型-在接口中使用索引类型时,编译器无法解析精确值_Typescript - Fatal编程技术网

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
};