这是我需要在Typescript中定义的函数调用
gen(settings: ISettings, enabled?: object, maps?: object): (v: string) => string;
其中的设置是:
interface ISettings {
mods: string[];
states: string[];
}
但是ISettings
中的数组值实际上与函数调用中的其他两个参数有关:enabled
和map
。
也许更好地理解一个例子。
gen({
mods: ['one', 'two'],
states: ['init', 'final']
}, {
one: true,
init: true
}, {
one: 'first',
two: 'second',
final: 'end'
}
);
如您所见:
就我所获得的代码而言,但这是行不通的。我希望代码完成建议第二个和第三个参数对象中的对象键,因为它们与第一个参数对象中的那些数组有关。
interface ISettings<TMods extends object, TStates extends object> {
mods: Array<keyof TMods & string>;
states: Array<keyof TStates & string>;
[other: string]: any;
}
function gen<
TMods extends object = {},
TStates extends object = {}
>(
settings: string | ISettings<TMods, TStates>,
enabled: Partial<Record<keyof (TMods & TStates), boolean>> = {},
maps: Partial<Record<keyof (TMods & TStates), string>> = {}
): string {
//function doesn't return anything yet
return '';
}
gen({
mods: ['one', 'two'],
states: ['disabled', 'fixed']
}, {
one: true,
disabled: true
}, {
one: 'first',
two: 'second',
fixed: 'static'
});
从建议的类型可以看出,enabled
和maps
参数可以定义settings
中提供的两个字符串数组的组合的成员的任何子集(或全部)宾语。这两个对象可以具有重叠的成员。
Partial<Record<keyof (TMods & TStates), ...>>
settings
参数定义了可能的对象成员,但是由于它们在函数体内的使用方式不同,它们被分成两个字符串数组enabled
对象将某些成员设置为 on maps
对象更改其输出名称(重新映射原始名称);输出将仅返回并重新映射启用了启用标志的输出。注意 :该代码基本上是试图为npm libs的
suit-cx.d.ts
和bem-classnames.d.ts
文件的代码定义如果您熟悉它们,则使用相同的名称。
答案 0 :(得分:0)
稍微简化类型,以便编译器仅需将键推断为字符串文字类型(而不是其他未知对象的键),就可以让编译器在编写第二和第三个参数时提供一些建议:
interface ISettings<TModsKeys extends string, TStatesKeys extends string> {
mods: Array<TModsKeys>;
states: Array<TStatesKeys>;
[other: string]: any;
}
function gen<
TModsKeys extends string,
TStatesKeys extends string
>(
settings: string | ISettings<TModsKeys, TStatesKeys>,
enabled: Partial<Record<TModsKeys | TStatesKeys, boolean>> = {},
maps: Partial<Record<TModsKeys | TStatesKeys, string>> = {}
): string {
//function doesn't return anything yet
return '';
}
gen({
mods: ['one', 'two', 'three'],
states: ['disabled', 'fixed']
}, {
one: true,
disabled: true,
}, {
one: 'first',
two: 'second',
fixed: 'static',
});