我有一个带有两个键的配置对象的函数。这些值是对象中键的数组。
a
类型的Config
值将从T
类型的对象中删除,但是b
值需要以某种方式转换仅对字符串值键有效。
结果是一个将类型T
作为显式参数的函数,并返回一个对类型T
的对象进行转换的函数:
interface Config<T extends Object, K extends keyof T> {
a?: K[] // keys to remove from T, this works fine
b?: K[] // keys to modify string value - want to constrain these
}
export function f<T extends Object>(config: Config<T, keyof T>): (row: T) => Partial<T> {
return function (row) {
// remove keys from config.a
// do something stringy with keys from config.b
}
}
这样称呼:
const fn = f<SomeType>({ a: [...], b: [...] })
是否有某种方法可以将b
界面中的Config
限制为仅字符串值的键?我尝试了所有可能想到的方法,但尝试的大多数方法都产生了语法错误。我现在正在通过将字符串值强制转换为string来解决此问题,因为类型系统不知道它们是字符串。有更好的方法吗?
答案 0 :(得分:1)
如果您不需要跟踪要删除/添加的键的实际并集,则可以从K
中删除Config
参数。从您的示例中,我认为这不是必需的。
要只获取某种类型的键,我们可以使用条件类型和映射类型:
interface Config<T extends Object> {
a?: (keyof T)[] // keys to remove from T, this works fine
b?: KeyOfValueType<T, string>[] // keys to modify string value - want to constrain these
}
type KeyOfValueType<T, TValue> = {[P in keyof T]: T[P] extends TValue ? P : never}[keyof T];
export function f<T extends Object>(config: Config<T>): (row: T) => Partial<T> {
return function (row) {
return null as any;
}
}
interface SomeType {
nr: number;
str: string
}
const fnOk = f<SomeType>({ a: ['nr'], b: ['str' ] })
const fnNok = f<SomeType>({ a: ['nr'], b: ['str', 'nr'] })