为什么字符串可以分配给Array <string>

时间:2018-03-07 12:11:26

标签: typescript

我有以下定义

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[]

所以我希望方法调用也不是错误的类型。

Playground sample

1 个答案:

答案 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
        }
    }
})