我想实现函数参数的类型检查,其中第二个参数的属性基于前一个参数的属性。
config
变量应仅包含values
数组中对象中存在的此类属性。属性应该是可选的(不需要在config
中包含所有属性,但不允许添加不同的属性。
请参阅示例代码:
type CustomType <T> = {
[K in keyof T]: number
};
type Config <T> = {
[K in keyof T]? : {
highPriority: boolean;
callback: (values: any[]) => number[];
}
};
const customFunction = <T>(values: T[], config: Config <T> ): Array <CustomType<T>> => {
// logic...
return [];
};
const values = [
{
foo: 'foo',
bar: 'bar'
},
{
foo: 'foo',
bar: 'bar'
}
];
// Should optionaly contain only "foo", "bar" properties in this example
const config = {
foo: {
highPriority: true,
callback: () => []
},
// not present in values objects
wrong: {
highPriority: true,
callback: () => []
}
};
// config should be marked with errors as "wrong" is not present in values objects
const result = customFunction(values, config);
在最后一行中,config
应标记为错误,因为它会引入wrong
属性,该属性在原始values
对象中不存在。
我可以通过实现config
的接口强制进行一些检查,但我认为这是不必要的,没有它就可以完成。
interface ISpecific {
foo: any,
bar: any
}
const values: ISpecific[] = [
{
foo: 'foo',
bar: 'bar'
},
{
foo: 'foo',
bar: 'bar'
}
];
const config: Config<ISpecific> = {
// ...
// wrong property is marked as error
}
更新:
config
在其他地方定义,不了解values
变量customFunction
用于整个应用程序的多个位置,因此将config
作为对象文字传递是不可行的。任何帮助?
答案 0 :(得分:3)
如果将对象文字直接分配给给定类型的变量/参数,
Typescript仅检查多余属性,如文档here所述。在您的情况下,您可以显式键入config
,或直接使用对象文字作为参数:
const values = [
{
foo: 'foo',
bar: 'bar'
},
{
foo: 'foo',
bar: 'bar'
}
];
// We type relative to values, no need for the extra interface
const config: Config<typeof values[number]> = {
foo: {
highPriority: true,
callback: () => []
},
// will be an error
wrong: {
highPriority: true,
callback: () => []
}
};
//Or pass the object literal directly
const result2 = customFunction(values, {
foo: {
highPriority: true,
callback: () => []
},
// error
wrong: {
highPriority: true,
callback: () => []
}
});
另一种选择是使用条件类型和额外参数来触发错误,如果传递的类型具有额外的属性:
type NoExtraProperties<TSource, TTarget> = Exclude<keyof TSource, keyof TTarget> extends never ? true : "Extra properties detected";
const customFunction = <T, TConfig extends Config<T>>(values: T[], config: TConfig, validate: NoExtraProperties<TConfig, T>): Array<CustomType<T>> => {
// logic...
return [];
};
// Argument of type 'true' is not assignable to parameter of type '"Extra properties detected"'.
const result = customFunction(values, config, true);
游乐场link