【发布时间】:2019-03-26 10:20:59
【问题描述】:
我需要提供一个适配器函数,它接受一个对象并返回一个或多个给定类型的值。我正在尝试编写一个通用函数,该函数将在给定对象属性名称的情况下生成这样的适配器函数,其中属性名称仅限于其值为给定类型的属性。
例如,考虑数字属性的简单情况:
type Adapter<T> = (from: T) => number
我想我想做这样的事情:
type NumberFields<T> = {[K in keyof T]: T[K] extends number ? K : never}[keyof T]
function foo<T>(property: NumberFields<T>) {
return function(from: T) {
return from[property]
}
}
当NumberFields 的参数不是泛型时,TypeScript 就足够开心了:
interface Foo {
bar: number
}
function ok<T extends Foo, K extends NumberFields<Foo>>(property: K): Adapter<T> {
return function(from: T): number {
return from[property] // ok
}
}
但是,在一般情况下,TypeScript 不想识别 from[property] 只能是一个数字:
function bar<T, K extends NumberFields<T>>(property: K): Adapter<T> {
return function(from: T): number {
return from[property] // error: Type 'T[K]' is not assignable to to type 'number'
}
}
function baz<T, K extends NumberFields<T>>(property: K): Adapter<T> {
return function(from: T): T[K] { // error: Type '(from: T) => T[K]' is not assignable to type 'Adapter<T>'
return from[property]
}
}
为什么它在类型受到约束时起作用,但在真正的泛型情况下却不起作用?
我查看了许多 SO 问题,其中 Narrowing TypeScript index type 似乎最接近我想要的,但是类型保护在这里没有用,因为类型应该是通用的。
【问题讨论】:
标签: typescript generics return-type