如何在Typescript中使用联合类型返回值?
我正在尝试在Typescript 1.5-beta中使用(via)。在我的代码中,我想使用具有以下签名的如何在Typescript中使用联合类型返回值?,typescript,Typescript,我正在尝试在Typescript 1.5-beta中使用(via)。在我的代码中,我想使用具有以下签名的exec函数: export function exec(command: string, options: ExecOptions): ExecOutputReturnValue | child.ChildProcess; export interface ExecOutputReturnValue { code: number; output: string; } 如果
exec
函数:
export function exec(command: string, options: ExecOptions): ExecOutputReturnValue | child.ChildProcess;
export interface ExecOutputReturnValue
{
code: number;
output: string;
}
如果我按如下方式导入并使用库(在正常ES6中,JavaScript工作得非常好)
Typescript编译器给了我错误TS2339:类型“ChildProcess | ExecOutputReturnValue”上不存在属性“code”
如何以类型安全的方式访问.code?当您有联合类型时,您将在使用它时看到任何共享成员 如果要使用更具体的成员,则需要使用类型保护。在类型保护内部,您可以访问该类型的所有特定成员 以下是一个简化示例:
declare class Test {
example(): string | number;
}
var x = new Test();
var y = x.example();
if (typeof y === 'string') {
// In here, y has all the members of a string type
y.
} else {
// In here, y has all the members of a number type
y.
}
当您处理无法应用typeof
检查的类型时,您需要告诉编译器“您最了解”:
constcode=($.exec(命令,{silent:true})).code;
这是一个老问题,但如果有人遇到它,这可能会有所帮助。在TS的较新版本中,使用带有类型谓词的用户定义类型保护比简单地“告诉编译器您最了解”更安全,并且在您认为您最了解但实际上不了解的情况下可以帮助避免运行时错误:-)
使用OPs示例:
import * as $ from 'shelljs';
// our user-defined type guard, note the return type
const isExecOutput = (result: ExecOutputReturnValue | child.ChildProcess): code is ExecOutputReturnValue => {
return (result as ExecOutputReturnValue).code !== undefined;
}
const result: ExecOutputReturnValue | child.ChildProcess = $.exec(command, { silent: true });
if (isExecOutput(result)) {
doSomething(result.code); // safe!
} else {
// ... accessing the other type's members is safe here
}
实现此功能的关键是
isExecOutput
函数的返回类型:代码为ExecOutputReturnValue
。调用一个类型谓词,这使得像这样的用户定义类型保护成为可能。可以找到官方文档。这似乎意味着您只能“看到”两种类型共享的属性。child.ChildProcess
是否也定义了名为code的属性?不可否认,我刚刚学会了什么是工会类型。。。你试过将它铸造成想要的类型吗?试过铸造,似乎不起作用。从技术上讲,这听起来很合理,但我想知道:编译后的JavaScript如何知道或能够解析类型?在上面的shelljs示例中,这两种类型都是对象,它们都不一定具有可识别的属性!您必须使用类型断言:(啊,谢谢。这是我要找的构造。
const code = (<ExecOutputReturnValue >$.exec(command, { silent: true })).code;
import * as $ from 'shelljs';
// our user-defined type guard, note the return type
const isExecOutput = (result: ExecOutputReturnValue | child.ChildProcess): code is ExecOutputReturnValue => {
return (result as ExecOutputReturnValue).code !== undefined;
}
const result: ExecOutputReturnValue | child.ChildProcess = $.exec(command, { silent: true });
if (isExecOutput(result)) {
doSomething(result.code); // safe!
} else {
// ... accessing the other type's members is safe here
}