我很难理解这个标题,但代码示例非常简单:

// Setup
interface Dog {
    name: string;
}

interface Dachshund extends Dog {
    length: number;
}

function isDachshund (dog: Dog): dog is Dachshund {
    return (dog as Dachshund).length !== undefined;
}

// Problem
// We have an object that could match two different interfaces
let unknownDog: Dog | Dachshund = { name: "Rufus" };

// If it's not this specific interface, add the missing property
if (!isDachshund(unknownDog)) {
    (unknownDog as Dachshund).length = 5;
}

unknownDog // compiler still thinks Dog | Dachshund, but we know for certain it's a Dachshund at this point

有没有可能让TypeScript编译器推断我们已经添加了必要的属性来缩小联合类型的范围?有没有一种不同的方式来组织我的类型来避免这种问题?

推荐答案

有趣的问题.

据我所知,(如果我错了,一定要有人纠正我),TypeScript看起来根本不支持您在这里特别try 的操作.

参见github的这期:https://github.com/microsoft/TypeScript/issues/27568

基本上,你要做的是让TypeScript知道你对一个更宽类型的对象所做的Mutations ,并正确推断出更窄的类型.

上述Github问题似乎表明"不,太难了".

请注意,当不使用类型注释时,TypeScript不会跟踪排序的变化!

const rufus = {
    name: "foo"
}; 


rufus.length = 9; //Property 'length' does not exist on type '{ name: string; }'.(2339)

我在这里要做的只是不改变对象,而是声明新对象:


function usesADog(unknownDog: Dog | Dachshund){

    const dogToUse = isDachshund(unknownDog) ? unknownDog: {...unknownDog, length: 5}; 

    dogToUse; //const dogToUse: Dachshund

}

Playground

Typescript相关问答推荐

具有映射返回类型的通用设置实用程序

在TypScript手册中可以视为接口类型是什么意思?

Angular 17 Select 错误core.mjs:6531错误错误:NG 05105:发现意外合成监听器@transformPanel.done

基于平台的重定向,Angular 为16

隐式键入脚本键映射使用

等待用户在Angular 函数中输入

TypeScrip省略了类型参数,仅当传递另一个前面的类型参数时才采用默认类型

如何避免推断空数组

MatTool提示在角垫工作台中不起作用

寻址对象中路径的泛型类型

正确使用相交类型的打字集

编译TypeScrip项目的一部分导致错误

复选框Angular 在Ngfor中的其他块中重复

为什么上下文类型在`fn|curred(Fn)`的联合中不起作用?

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

Typescript不允许在数组中使用联合类型

参数未映射泛型返回类型

基于参数的 TS 返回类型

如何按成员资格排除或 Select 元组?

如何在没有空接口的情况下实现求和类型功能?