TypeScript 抱怨 array.map 不存在于字符串 [] 类型的数组中

TypeScript complaining that array.map is not present on array of type string[]

我有一个使用 TypeScript 的 Angular 2 项目。我不明白为什么 TypeScript 实时编译器会抱怨 info.map

Error message: unresolved function or method map()

当我在浏览器中 运行 时, 工作正常,但我不明白为什么发生了,更重要的是 TypeScript 如何确定我所在的 if /else 分支。

代码:

let addInfo = (info: string|string[]) =>  {
        if(_.isString(info)){

            console.log('info is a string');
            infos.push(info);

        }else if(_.isArray(info)){

            console.log('info is an array');
            info.map( x => { infos.push(x) }); // here is the compiling error- map is red.
        }
 }

这是一张快照:

Typescript 编译器无法将 lodash 的函数调用识别为类型检查。您可以尝试 "if(info instanceof String)" 并且在 "else" 分支中打字稿可以假设 "info" 是数组。

这对我有用 typescript playground:

let addInfo = (info: string|string[]) =>  {
    if(info instanceof String){
        info;
    } else {
        info.map(s => s);
    }
 }

更新

感谢@Tamas Hegedus,分享了有关自定义类型保护的知识。我以前没有听说过他们。我决定在这里引用 Typescript documentation 关于用户定义类型保护的引述:

It just so happens that TypeScript has something called a type guard. A type guard is some expression that performs a runtime check that guarantees the type in some scope. To define a type guard, we simply need to define a function whose return type is a type predicate:

function isFish(pet: Fish | Bird): pet is Fish {
    return (<Fish>pet).swim !== undefined;
}

pet is Fish is our type predicate in this example. A predicate takes the form parameterName is Type, where parameterName must be the name of a parameter from the current function signature.

简单的解决方案:

我有 @types/lodash/index.d.ts 文件,但我认为是旧版本。 一旦我安装了新版本 - 一切都按预期进行。

所以对于拥有 Angular2 CLI 项目的人来说,只需 运行: npm install @types/lodash :)