声明仅应用特定类型的对象键的方法的方法是什么?
What is the way to declare a method that apply only specific type of key of object?
我有这样的界面:
interface Element {
id: string;
name: string;
relatedElementsIds: string[];
functionalitiesIds: string[];
}
我想调用一个只接受类型为 string[]
的键的方法。
所谓的喜欢:
test(element, 'relatedElementsIds'); // Ok
test(element, 'functionalitiesIds'); // Ok
test(element, 'id'); // Error
test(element, 'name'); // Error
在不特定于接口的当前属性的情况下声明方法的好方法是什么?
interface Element {
id: string;
name: string;
relatedElementsIds: string[];
functionalitiesIds: string[];
}
declare var element: Element
/**
* Get union of all values
*/
type Values<T> = T[keyof T]
/**
* If Property is string[] - return this property
* If Property is not string[] - return never
*/
type Filter<T> = {
[Prop in keyof T]: T[Prop] extends string[] ? Prop : never
}
/**
* Get union of all filtered property.
* Keep in mind that 'relatedElementsIds' | never evaluates to 'relatedElementsIds'
* This is how you can get rid of never
*/
type GetKeys<T> = Values<Filter<T>>
function test<Obj extends Element, Key extends GetKeys<Obj>>(obj: Obj, key: Key) {
}
test(element, 'relatedElementsIds'); // Ok
test(element, 'functionalitiesIds'); // Ok
test(element, 'id'); // Error
test(element, 'name'); // Error
type StringArrayKeyOf<T> = keyof {
[K in keyof T as (T[K] extends string[] ? K : never)]: T[K]
}
declare function test(e: Element, key: StringArrayKeyOf<Element>): void
我有这样的界面:
interface Element {
id: string;
name: string;
relatedElementsIds: string[];
functionalitiesIds: string[];
}
我想调用一个只接受类型为 string[]
的键的方法。
所谓的喜欢:
test(element, 'relatedElementsIds'); // Ok
test(element, 'functionalitiesIds'); // Ok
test(element, 'id'); // Error
test(element, 'name'); // Error
在不特定于接口的当前属性的情况下声明方法的好方法是什么?
interface Element {
id: string;
name: string;
relatedElementsIds: string[];
functionalitiesIds: string[];
}
declare var element: Element
/**
* Get union of all values
*/
type Values<T> = T[keyof T]
/**
* If Property is string[] - return this property
* If Property is not string[] - return never
*/
type Filter<T> = {
[Prop in keyof T]: T[Prop] extends string[] ? Prop : never
}
/**
* Get union of all filtered property.
* Keep in mind that 'relatedElementsIds' | never evaluates to 'relatedElementsIds'
* This is how you can get rid of never
*/
type GetKeys<T> = Values<Filter<T>>
function test<Obj extends Element, Key extends GetKeys<Obj>>(obj: Obj, key: Key) {
}
test(element, 'relatedElementsIds'); // Ok
test(element, 'functionalitiesIds'); // Ok
test(element, 'id'); // Error
test(element, 'name'); // Error
type StringArrayKeyOf<T> = keyof {
[K in keyof T as (T[K] extends string[] ? K : never)]: T[K]
}
declare function test(e: Element, key: StringArrayKeyOf<Element>): void