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】:如果您告诉value
是fooInterface
或string
类型,则必须先检查类型,然后才能使用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 接口和原语的主要内容,如果未能解决你的问题,请参考以下文章