我有以下定义
type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>;
};
interface IMockHelprConf {
clientPolicys: DeepPartial<IExchangeSettings>;
}
declare interface IExchangeSettings {
localPolicy: ILocalPolicys;
signature: ISignatures;
}
declare interface ILocalPolicys {
maxFileSize?: number;
filePattern?: string[];
reciverPattern?: string[];
}
function test(conf: IMockHelperConf){
...
}
我现在可以使用以下对象调用函数test(conf)
:
test({
clientPolicys: {
localPolicy: {
reciverPattern: '@test.de$'
}
}
}
这不会导致错误。但我实际应该使用['@test.de$']
。否则,在“数组”上运行实际上会列出单个字符。
我的第一个问题是字符串实现string[]
,但是使用string[]
从字符串转换为as
会失败:Type 'string' cannot be converted to type 'string[]
。
所以我希望方法调用也不是错误的类型。
答案 0 :(得分:3)
问题是reciverPattern
的类型是DeepPartial<string[]>
。这意味着reciverPattern
没有强制属性,它可以具有string[]
的任何属性,但不需要这样做。由于您为其分配了一个字符串,因此该字符串是兼容的,如果您已经分配了一个对象文字,那么您将收到一个错误,因为检查了对象文字的额外属性,但字符串文字不是。
你想要的东西可以在Typescript 2.8 unsing条件类型中实现(在撰写本文时尚未发布但将于2018年3月发布,你可以通过npm install -g typescript@next
获得)。我们的想法是只对其他对象使用deep partial,而不是对基本类型或数组使用:
type DeepPartial<T> = {
[P in keyof T]?:
T[P] extends Array<any> ? T[P] :
T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// OK
test({
clientPolicys: {
localPolicy: {
reciverPattern: [""]
}
}
})
// Error
test({
clientPolicys: {
localPolicy: {
reciverPattern: "" // error
}
}
})