[英]Passing generic enum type as a parameter to a function in Typescript
我有两个具有相同变体但具有不同字符串值的字符串枚举。
它们被传递给相同的初始函数,该函数接受整个枚举(我认为我可以使用typeof
来做到这一点,但每个枚举应该有不同的回调。输入初始函数的最佳方法似乎是什么?
我拥有的这段代码不起作用,因为它抱怨我不能将typeof
与我的T
泛型参数一起使用。
enum OpsA {
Start = 'a_start',
Stop = 'a_stop'
}
enum OpsB {
Start = 'b_start',
Stop = 'b_stop'
}
type EitherOps = OpsA | OpsB
function doSomething <T extends EitherOps, U extends typeof T>(action: U, callback: (a: T) => void) {
console.log(action.Start)
callback(action.Start)
console.log(action.Stop)
callback(action.Stop)
}
// does something special for OpsA
const callbackForA = (a: OpsA) => console.log(a)
// does something else special for OpsB
const callbackForB = (b: OpsB) => console.log(b)
doSomething(OpsA, callbackForA)
doSomething(OpsB, callbackForB)
你的问题是T
是一个类型而不是一个值,所以typeof T
是一个类别错误。 您的困惑可能源于enum
声明将命名值和命名类型都带入范围的事实,并且名称恰好相同。 但是没有一般的规则,同名的值和类型之间有任何关系。
例如, enum OpsA { /* ... */ }
声明了值OpsA
(具有属性键Start
和Stop
的对象)和类型OpsA
(枚举对象的属性值类型的联合)。 当您将typeof OpsA
编写为类型时,您在谈论枚举对象的类型,而当您将OpsA
编写为类型时,您正在谈论枚举对象的属性值的类型。
但是,OpsA 类型是 OpsA 对象类型typeof OpsA
OpsA
属性类型这一事实不能以您可能试图做的方式概括。 没有规则说“给定类型T
有一个类型typeof T
其属性是类型T
”。 有关更多信息,请参阅相关问题的答案。
好吧,如果你不能写U extends typeof T
,你能做什么? 您希望U
成为其属性键为"Start"
或"Stop"
的对象类型。 让我们首先获取这些键的类型。 由于ObjA
和ObjB
值都有这些键,我们可以将其写为keyof typeof ObjA
或keyof typeof ObjB
:
type OpsKeys = keyof typeof OpsA;
// type OpsKeys = "Start" | "Stop"
如果我们想说U
应该是具有OpsKeys
键和T
类型值的对象类型,那么我们可以使用Record<K, V>
实用程序类型: U extends Record<OpsKeys, T>
。 像这样:
function doSomething<
T extends EitherOps,
U extends Record<OpsKeys, T>
>(action: U, callback: (a: T) => void) {
console.log(action.Start)
callback(action.Start)
console.log(action.Stop)
callback(action.Stop)
}
现在一切都在doSomething()
中按预期工作。 让我们确保它也适用于调用者:
doSomething(OpsA, callbackForA) // okay
doSomething(OpsB, callbackForB) // okay
doSomething(OpsA, callbackForB) // error
看起来不错。 如果您传入不适合action
参数的callback
参数,编译器会发出警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.