首页 > 解决方案 > 打字稿`in`运算符类型保护缩小仅作为文字

问题描述

使用运算符缩小类型是否in仅适用于文字,还是我遗漏了什么?请帮助我理解为什么会这样。

interface A {
    a: string;
}

interface B {
    b: number;
}

// This narrows the type correctly to A
function test(arg: A | B): string {
    if ('a' in arg) {
        return arg.a;
    }
    return arg.b.toFixed(2);
}

// This doesn't
function test2(arg: A | B): string {
    let a = 'a';
    if (a in arg) {
        return arg.a;
    }
    return arg.b.toFixed(2);
}

标签: typescripttypingtypeguards

解决方案


关于文档

对于 in x 表达式,其中 n 是字符串文字或字符串文字类型,x 是联合类型,“true”分支缩小到具有可选或必需属性 n 的类型,“false”分支缩小到具有可选或必需属性 n 的类型有一个可选的或缺少的属性 n。

所以,我敢打赌它只适用于文字

解决方法

interface A {
    a: string;
}

interface B {
    b: number;
}

// This narrows the type correctly to A
function test(arg: A | B): string {
    if ('a' in arg) {
        return arg.a;
    }
    return arg.b.toFixed(2);
}

const isIn = <T, Prop extends string>(obj: T, prop: Prop): obj is T & Record<Prop, unknown> => prop in obj
const isIn2 = <T, Prop extends string>(obj: T, prop: Prop): obj is T & Record<Prop, unknown> =>
    Object.prototype.hasOwnProperty.call(obj, prop)

// This doesn't
function test2(arg: A | B): string {
    const a: 'a' = 'a' as 'a';
    if (isIn(arg, a) /** OR isIn2(arg, a) */) {
        return arg.a; // A        
    }


    return arg.b.toFixed(2);
}


推荐阅读