gpt4 book ai didi

typescript - 如何使用泛型缩小 TypeScript 联合类型

转载 作者:行者123 更新时间:2023-12-03 18:52:56 24 4
gpt4 key购买 nike

我有一个更新状态的泛型函数(用例是动态处理 React 中表的更新),并使用泛型来确保调用该函数是类型安全的,但我不明白为什么 TypeScript 无法编译。
在函数本身中,Typescript 似乎没有使用所有可用信息来缩小类型,而是认为我仍在使用完整的联合。
它清楚地知道足够的参数来判断函数是否被正确调用,那么为什么在对实际实现进行类型检查时会失败呢?
row[field] = value 处失败.
最小示例:

type First = { a: string; b: string; c: string }
type Second = { b: string; c: string; d: string }
type Third = { c: string; d: string; e: string }

type State = {
first: First[]
second: Second[]
third: Third[]
}

const update = <
S extends State,
TK extends keyof State,
T extends S[TK],
R extends T[number],
F extends keyof R
>(
state: State,
tagName: TK,
rowIndex: number,
field: F,
value: R[F]
) => {
// fine
const tag = state[tagName]

// fine
const row = tag[rowIndex]
// keyof typeof row is now 'c'

// TYPE ERROR
row[field] = value
}

const state: State = {
first: [{ a: "", b: "", c: "" }],
second: [{ b: "", c: "", d: "" }],
third: [{ c: "", d: "", e: "" }],
}

// this succeeds as expected
update(state, "first", 0, "a", "new")

// and this fails as expected
// @ts-expect-error
update(state, "second", 0, "a", "new")
Playground

最佳答案

尝试这个:

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
}

关于typescript - 如何使用泛型缩小 TypeScript 联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66575817/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com