Typescript Unions 接口和原语

Posted

技术标签:

【中文标题】Typescript Unions 接口和原语【英文标题】:Typescript Unions interface and primitive 【发布时间】:2017-04-05 17:28:51 【问题描述】:

考虑这个例子

interface fooInterface 
    bar: any;

function(value: fooInterface | string)  
    value.bar 

错误是:类型'(fooInterface | string)'上不存在属性'bar'

我显然做错了什么。我想说的基本上是:value 要么是一个实现 fooInterface 的对象,要么是一个字符串。

我该怎么做?

谢谢

【问题讨论】:

是的,联合类型是正确的说法。但是如果它是一个字符串,它就没有bar 属性,所以这样访问它是错误的。你到底想做什么? 如果你确信值包含 fooInterface 值,你可以通过 (<fooInterface>value).bar(value as fooInterface).bar 让 TypeScript 相信你的真相。 【参考方案1】:

您不能使用value.bar,因为它绝对不安全。它可能是安全的(因为 value 可能是一个字符串),但编译器并不确定这一点,除非确定,否则它不会让您执行 .bar。您可能想要做的是使用type guard:

if (typeof value !== "string") 
    value.bar
   // This compiles happily, because inside this if, value has
   // type 'fooInterface'. That's because TS now knows it isn't a string,
   // so *must* be a fooInterface.

你可以玩弄这个in the typescript playground:注意只有一个value.bar 失败了,因为它知道只有那个是错误的。

如果你不能/不想这样做,你可以只告诉编译器你知道你在用类型断言做什么(例如var definitelyFoo = <fooInterface> value),但是守卫通常是更好的选择。

【讨论】:

有道理,它迫使我的代码更加健壮,谢谢。【参考方案2】:

如果您告诉valuefooInterfacestring 类型,则必须先检查类型,然后才能使用value。在您的情况下,您只需使用typeof 检查value 是否为string。如果不是,则为fooInterface

interface fooInterface 
    bar: any;

function(value: fooInterface | string) 
    if (typeof value === "string") 
        // The compiler now knows that value is string
    
    else 
        /* The compiler is smart and knows that the value
           must be of type fooInterface. */

        value.bar 
    

在其他情况下,您将不得不使用 instanceof(用于检查对象是否是 typeof 特定类)或您的 own type checks(如果有多个接口或自定义类型)。

【讨论】:

以上是关于Typescript Unions 接口和原语的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:对象和原语之间的keyof typeof联合总是永远不会

golang 中io包用法

简析 Golang IO 包

Go 内置库 IO interface

Go 流式 IO

keil4 #pragma anon_unions