声明仅应用特定类型的对象键的方法的方法是什么?

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

Playground

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