gpt4 book ai didi

typescript - typescript 中的依赖类型 - 通过属性名称类型确定类型

转载 作者:行者123 更新时间:2023-12-05 06:58:23 26 4
gpt4 key购买 nike

我试图让类型依赖于传递参数的类型。一个人为的例子是:

type NS = "num" | "str"
type Data<T extends NS> = T extends "num" ? number : string
type Func<T extends NS> = (x: Data<T>) => Data<T>
type Funcs = {[T in NS]: Func<T>}
type Obj = {[T in NS]: Data<T>}
const funcs: Funcs = {
num: (x) => x * 2,
str: (x) => x + x
}

function useFunc<T extends NS>(ns: T, obj: Obj): Data<T> {
const f = funcs[ns]
const x = obj[ns]
return f(x)
}

问题是 f(x)类型为 number | string而不是 Data<T> ,这似乎是由 f 引起的具有类型 Funcs[T]而不是 Func<T> . x也有类型 Obj[T]而不是 Data<T> .

因此 typescript 无法推断出 Funcs[T]Func<T>是一样的,Obj[T]Data<T>是一样的,即使那是FuncsObj被定义...

我可以通过对所有内容进行类型转换使其工作,但它违背了使用类型的目的:

function useFunc<T extends NS>(ns: T, obj: Obj): Data<T> {
const f = funcs[ns] as Func<T>
const x = obj[ns] as unknown as Data<T>
// note the double-cast as Obj[T] and Data<T> "do not sufficiently overlap"
return f(x)
}

有没有办法让它在 typescript 中工作?

编辑:

我知道它可以通过这种方式工作,适用于调用站点,但从代码重用的角度来看毫无意义 - 在不同类型上组合相同的逻辑是这样做的实际动机,并且在这样就简单地重复了。

function useFunc<T extends NS>(ns: T, obj: Obj): Data<T>
function useFunc(ns: NS, obj: Obj): Data<NS> {
if (ns === "num") {
const f = funcs[ns]
const x = obj[ns]
return f(x)
}

const f = funcs[ns]
const x = obj[ns]
return f(x)
}

有没有办法在不失去类型安全的情况下避免这种重复?

最佳答案

主要问题是您试图调用 f内部功能 useFunc当 TS 推断 f签名为 (x: never) => string | numer .此签名与 funcs 中的每个签名都不兼容对象。

另外,正如我所说的签名useFunc<T extends NS>(ns: T, obj: Obj): Data<T>应该简化,甚至更正为 useFunc<T extends NS>(ns: T, obj: Data<T>): Data<T> .那是因为 TS 应该知道您将传递给 f 的数据类型。能够进行类型检查。此外,需要进行上述修改的另一个原因是 useFunc函数调用仅适用于 ns等于 "num""str" , 但不是同时。由于上述原因,obj参数类型将为 Data<"num">Data<"str"> .因此,将其键入为 Obj 是错误的.

修改最少的可能解决方案是:

function useFunc<T extends NS>(ns: T, arg: Data<T>): Data<T> {
const f = funcs[ns]
return (f as Func<T>)(arg)
}

关于typescript - typescript 中的依赖类型 - 通过属性名称类型确定类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64631894/

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