如何使用泛型缩小TypeScript联合类型的范围
我有一个更新状态的泛型函数(用例在React中动态处理表的更新),并使用泛型来确保调用该函数是类型安全的,但我不理解为什么TypeScript不会编译 在函数本身中,似乎Typescript没有使用所有可用信息来缩小类型范围,而是认为我仍在使用完整的联合。 它清楚地知道关于参数的足够多的信息来判断函数是否被正确调用,那么为什么它在检查实际实现的类型时失败了呢 在如何使用泛型缩小TypeScript联合类型的范围,typescript,typescript-generics,union-types,Typescript,Typescript Generics,Union Types,我有一个更新状态的泛型函数(用例在React中动态处理表的更新),并使用泛型来确保调用该函数是类型安全的,但我不理解为什么TypeScript不会编译 在函数本身中,似乎Typescript没有使用所有可用信息来缩小类型范围,而是认为我仍在使用完整的联合。 它清楚地知道关于参数的足够多的信息来判断函数是否被正确调用,那么为什么它在检查实际实现的类型时失败了呢 在行[字段]=值时失败 最小示例: type First={a:string;b:string;c:string} 键入Second={b
行[字段]=值时失败
最小示例:
type First={a:string;b:string;c:string}
键入Second={b:string;c:string;d:string}
类型Third={c:string;d:string;e:string}
类型状态={
第一:第一[]
第二:第二[]
第三:第三[]
}
常数更新=<
它扩展了国家,
作为国家的一部分,
T扩展S[TK],
R扩展T[number],
F扩展了R的键
>(
州:州,,
标记名:TK,
行索引:编号,
字段:F,
数值:R[F]
) => {
//好的
常量标记=状态[标记名]
//好的
常量行=标记[rowIndex]
//行的typeof现在为“c”
//类型错误
行[字段]=值
}
常量状态:状态={
第一:[{a:,b:,c::}],
第二个:[{b:,c:,d::}],
第三:[{c:,d:,e::}],
}
//这正如预期的那样成功
更新(状态为“第一”,0,“a”,“新”)
//但这并没有达到预期的效果
//@ts预期错误
更新(状态为“第二”,0,“a”,“新”)
试试这个:
const update = <
TK extends keyof State,
F extends keyof State[TK][number]
>(
state: State,
tagName: TK,
rowIndex: number,
field: F,
value: State[TK][number][F]
) => {
// fine
const tag = state[tagName]
// fine
// The type annotation here is required
// (otherwise the type is inferred as First | Second | Third)
const row: State[TK][number] = tag[rowIndex]
// now also fine
row[field] = value
}
const更新=<
作为国家的一部分,
F国家元首[TK][人数]
>(
州:州,,
标记名:TK,
行索引:编号,
字段:F,
值:状态[TK][number][F]
) => {
//好的
常量标记=状态[标记名]
//好的
//此处的类型注释是必需的
//(否则类型推断为第一|第二|第三)
常量行:状态[TK][number]=标记[rowIndex]
//现在也可以了
行[字段]=值
}
谢谢,效果很好。请注意,这需要两个阶段的常量行:…
部分,并将F的类型更改为不仅仅是keyof R
。不知道为什么TS不能解决这个问题,但请记住这一点