我正在尝试编写一个泛型函数,其中使用泛型类型来键入其参数。
这是这个参数的一部分:
type Configuration<T> = {
masterdata: T[],
target: ????
}
我在输入 target
属性时遇到问题。我希望它是特定类(MtmFormComponent
,当前类)中的任何属性的名称,但具有属性类型为 T[]
的约束。
我的目标是写:this[configuration.target] = configuration.masterdata;
。
我已经到了一半。以下是我现在输入 target
的方式:
type MtmFormComponentPropertyOfType<T, K extends keyof MtmFormComponent> = MtmFormComponent[K] extends T[] ? K : never;
type DropdownAutocompleteConfiguration<T, K extends keyof MtmFormComponent> = {
masterdata: T[],
targetFilteredList: MtmFormComponentPropertyOfType<T, K>,
};
在声明类型为 DropdownAutocompleteConfiguration
的对象时,一切都很好,并且我的 IDE 的自动完成功能正确地限制了我只使用导致与 masterdata
的值相同类型的键。所以我的类型似乎定义正确。
我的问题是在我的通用函数中使用该对象时:
private setupDropdownAutocompleteBehaviour<T, K extends keyof MtmFormComponent>(configuration: DropdownAutocompleteConfiguration<T, K>): void {
this[configuration.targetFilteredList] = configuration.masterdata;
// ...
}
此处,this[configuration.targetFilteredList]
表达式给出以下错误:
类型 'T[]' 不能分配给类型 'this[Currency[] extends T[] ? "filteredCurrencyList" : never] & this[PriceUnit[] extends T[] ? "filteredPriceUnits" : never] & this[Subscription[] extends T[] ? “订阅”:从不]'。
类型 'T[]' 不能分配给类型 'this[Currency[] extends T[] ? "filteredCurrencyList" : 从不]'.
类型“T[]”不可分配给类型“货币[]”。
“T”类型不能分配给“货币”类型。
据我了解,在函数内部,TypeScript 完全解析了 this[configuration.targetFilteredList]
的类型,而不是依赖于它是 T[]
的事实。从我的 IDE 的自动完成功能来看,我确信我不能拥有 target
的值,这会导致类型与 masterdata
之一不兼容。
我不知道从那里开始做什么:/
感谢您的帮助:)
答案 0 :(得分:0)
在这种特殊情况下,您是否必须使您的函数在目标属性键上通用?
举个具体的例子,假设 MtmFormComponent
是这样定义的
interface MtmFormComponent {
foo: string[];
bar: string[];
baz: number[];
qux: string;
}
现在,我们想要一个类型,它为我们提供类型 T
的所有属性名称,其中属性名称映射到一个 U[]
值。我们可以这样定义这个类型:
type ArrayValuedProps<T, U> = { [K in keyof T]: (T[K] extends U[] ? K : never) }[keyof T]
这样,我们得到
ArrayValuedProps<MtmFormComponent, string> = { foo: "foo"; bar: "bar"; baz: never; qux: never }[keyof MtmFormComponent]
= { foo: "foo"; bar: "bar"; baz: never; qux: never }["foo" | "bar" | "baz" | "qux"]
= "foo" | "bar" | never
= "foo" | "bar"
同理,ArrayValuedProps<MtmFormComponent, number>
等价于类型 "baz"
;
使用它,我们可以像这样定义您的 Configuration<T>
类型:
type Configuration<T> = {
masterdata: T[],
target: ArrayValuedProps<MtmFormComponent, T>
}
并且我们可以完全避免将目标键作为类型参数放入。