首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型保护是否仅在返回true时缩小类型范围?

类型保护是否仅在返回true时缩小类型范围?
EN

Stack Overflow用户
提问于 2021-09-29 15:20:40
回答 1查看 43关注 0票数 2

我的印象是,接受多个类型instanceOfA(arg: A | B | C): arg is A的类型保护会将类型限制为A (当保护返回true时)或B | C (当保护返回false时)。

然而,对于下面的instanceOfB,返回false似乎会将类型缩小到never,而true根本不会缩小。类型保护实际上是否只在返回true时缩小类型范围?或者我误解了结果,在这种情况下,为什么会缩小到never

代码语言:javascript
复制
// Structures
interface A {
    value: string
    children: B[]
}

interface B {
    value: string
}

// Example functions
function doSomething1(arg: A | B) {
    if (instanceOfA(arg)) {
        console.log(`A: ${arg.value}`) // Type of arg is A
    } else {
        console.log(`B: ${arg.value}`) // Type of arg is B
    }
}

function doSomething2(arg: A | B) {
    if (instanceOfB(arg)) {
        console.log(`B: ${arg.value}`) // Type of arg is A | B
    } else {
        console.log(`A: ${arg.value}`) // Type of arg is never
    }
}

// Typeguards
function instanceOfA(ab: A | B): ab is A {
    return ab.hasOwnProperty('children')
}

function instanceOfB(ab: A | B): ab is B {
    return !ab.hasOwnProperty('children')
}
EN

回答 1

Stack Overflow用户

发布于 2021-09-29 15:50:59

问题是,这是一个理论问题,还是你有一个现实世界的问题?如果是第二个,我会说通过没有什么属性来识别一个类型是错误的。

如果你阅读the narrowing section in the typescript book,他们有一个例子,他们使用类型保护来通过检查宠物是否会游泳来区分FishBird (这本身就是一个相当宽松的假设)。但你所做的(转换成鸟,鱼的例子)基本上是在说:“如果它不会游泳,它一定是一只鸟”。这样做似乎不是特别合乎逻辑(正如评论中指出的那样,如果只有鱼和鸟可供选择,这个假设是有效的)。

我不认为instanceOfB是明智的。TypeScript允许将不同的类型分配给彼此,如果它们有足够的重叠,并且A总是可以分配给B,因为它完全覆盖了它拥有的所有属性。一旦你给B添加了一些A没有的属性,这个问题就会消失。

例如,这将是非常好的typescript:

代码语言:javascript
复制
const a: A = {value: 'this is a', children: []};
const b: B = {value: 'this is b'};

function printValue(subject: {value: string}) {
    console.log(subject.value);
}

如果你这样做(例如),你的支票就会开始工作:

代码语言:javascript
复制
interface B {
    value: string
    other: string;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69379200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档