有没有办法在打字稿中描述一种 "keyfor" ?
is there a way to describe a kind of "keyfor" in typescript?
有什么方法可以表达一个对象的键-属性应该受相关值的限制?与 keyof 等效的东西,但与给定键相关的值?
const objectAction = <T extends object>(obj: T): void => obj;
const onlyForObjects = <T extends object>(obj: T, key: keyof T): void =>
objectAction(obj[key])
应该可以
onlyForObjects<{ a: number, b: object }>({ a: 0, b: {} }, 'b');
应该不行
onlyForObjects<{ a: number, b: object }>({ a: 0, b: {} }, 'a');
如果我没有正确理解你的问题,那么下面就是你要找的:
type ObjKeys<T> = {
[P in keyof T]: T[P] extends Record<any, any> ? P : never
}[keyof T]
const objectAction = <T>(obj: T): void => console.log(obj)
const onlyForObjects = <T>(obj: T, key: ObjKeys<T>): void => objectAction(obj[key])
onlyForObjects<{ a: number; b: Record<string, unknown> }>({ a: 0, b: {} }, 'b') // compiles
onlyForObjects<{ a: number; b: Record<string, unknown> }>({ a: 0, b: {} }, 'a') // does not compile
您可以使用泛型 Record
constraint 作为类型参数 T
:
const onlyForObjects = <T extends Record<K, object>, K extends string>(
obj: T, key: K): void => { }
onlyForObjects({ a: 0, b: {} }, 'b'); // works
onlyForObjects({ a: 0, b: {} }, 'a'); // error
这里是live code sample.
有什么方法可以表达一个对象的键-属性应该受相关值的限制?与 keyof 等效的东西,但与给定键相关的值?
const objectAction = <T extends object>(obj: T): void => obj;
const onlyForObjects = <T extends object>(obj: T, key: keyof T): void =>
objectAction(obj[key])
应该可以
onlyForObjects<{ a: number, b: object }>({ a: 0, b: {} }, 'b');
应该不行
onlyForObjects<{ a: number, b: object }>({ a: 0, b: {} }, 'a');
如果我没有正确理解你的问题,那么下面就是你要找的:
type ObjKeys<T> = {
[P in keyof T]: T[P] extends Record<any, any> ? P : never
}[keyof T]
const objectAction = <T>(obj: T): void => console.log(obj)
const onlyForObjects = <T>(obj: T, key: ObjKeys<T>): void => objectAction(obj[key])
onlyForObjects<{ a: number; b: Record<string, unknown> }>({ a: 0, b: {} }, 'b') // compiles
onlyForObjects<{ a: number; b: Record<string, unknown> }>({ a: 0, b: {} }, 'a') // does not compile
您可以使用泛型 Record
constraint 作为类型参数 T
:
const onlyForObjects = <T extends Record<K, object>, K extends string>(
obj: T, key: K): void => { }
onlyForObjects({ a: 0, b: {} }, 'b'); // works
onlyForObjects({ a: 0, b: {} }, 'a'); // error
这里是live code sample.