TypeScript 具有相同参数的多种返回类型
Posted
技术标签:
【中文标题】TypeScript 具有相同参数的多种返回类型【英文标题】:TypeScript multiple return types with identical parameters 【发布时间】:2017-03-07 15:33:00 【问题描述】:背景
为了融入 TypeScript 的精神,我正在我的组件和服务中编写完全类型化的签名,这扩展到了我对 angular2 表单的自定义验证函数。
我知道I can overload a function signature,但这要求每个返回类型的参数都不同,因为tsc
将每个签名编译为单独的函数:
function pickCard(x: suit: string; card: number; []): number;
function pickCard(x: number): suit: string; card: number; ;
function pickCard(x): any /*common logic*/ ;
我也知道我可以返回一个类型(如 Promise),它本身可以是多个子类型:
private active(): Promise<void|null> ...
但是,在 angular2 自定义表单验证器的上下文中,单个签名(FormControl
类型的一个参数)可以返回两种不同的类型:带有表单错误的 Object
,或 null
表示控件没有错误。
这显然行不通:
private lowercaseValidator(c: FormControl): null;
private lowercaseValidator(c: FormControl): Object
return /[a-z]/g.test(c.value) ? null : lowercase: this.validationMessages.lowercase ;
也没有
private lowercaseValidator(c: FormControl): null|Object ...
private lowercaseValidator(c: FormControl): <null|Object> ...
(有趣的是,我收到以下错误,而不是提供更多信息:
error TS1110: Type expected.
error TS1005: ':' expected.
error TS1005: ',' expected.
error TS1128: Declaration or statement expected.
)
TL;DR
我是否只是使用
private lowercaseValidator(c: FormControl): any ...
这似乎否定了拥有类型签名的优势?
更一般地说,期待 ES6
虽然这个问题的灵感来自于框架直接处理的 angular2 表单验证器,因此您可能不关心声明返回类型,但它仍然普遍适用,尤其是考虑到像 function (a, b, ...others)
这样的 ES6 构造
也许避免编写可以返回多种类型的函数只是更好的做法,但由于 javascript 的动态特性,它相当地道。
参考文献
TypeScript function overloading Typescript syntax for a function returning observable or multiple type https://github.com/Microsoft/TypeScript/issues/11700 https://github.com/Microsoft/TypeScript/issues/10727(...spread)
https://github.com/Microsoft/TypeScript/issues/10571< , , type>
【问题讨论】:
你为什么需要空值?它不是一个单独的类型,Object 可以为 null。 (1) 不要使用Object
,而是使用any
。 (2) 这个:private lowercaseValidator(c: FormControl): null|Object ...
应该可以工作。
null | Object
似乎适用于the playground
@SamiKuhmonen Kickself:我没有考虑到这一点。我想我过度思考了强调它将返回“无”或“某物”这一事实的具体需求。也就是说,问题的中间部分仍然(也许)适用。
这不是我的意思,使用Object
几乎就像使用any
,但是:“any 类型是使用现有 JavaScript 的一种强大方式,允许您逐步选择加入和在编译期间选择退出类型检查。您可能希望 Object 扮演类似的角色,就像它在其他语言中一样。但是 Object 类型的变量只允许您为它们分配任何值 - 您不能调用任意方法它们,甚至是真实存在的”(typescriptlang.org/docs/handbook/basic-types.html#any)
【参考方案1】:
好的,如果你想拥有正确的类型,这是正确的方法:
type CustomType = lowercase: TypeOfTheProperty ;
// Sorry I cannot deduce type of this.validationMessages.lowercase,
// I would have to see the whole class. I guess it's something
// like Array<string> or string, but I'm not Angular guy, just guessing.
private lowercaseValidator(c: FormControl): CustomType | null
return /[a-z]/g.test(c.value) ? null : lowercase: this.validationMessages.lowercase ;
更一般的例子
type CustomType = lowercase: Array<string> ;
class A
private obj: Array<string>;
constructor()
this.obj = Array<string>();
this.obj.push("apple");
this.obj.push("bread");
public testMethod(b: boolean): CustomType | null
return b ? null : lowercase: this.obj ;
let a = new A();
let customObj: CustomType | null = a.testMethod(false);
// If you're using strictNullChecks, you must write both CustomType and null
// If you're not CustomType is sufficiant
【讨论】:
我在使用返回多种类型的方法时遇到问题。如果我有自己的方法返回 CustomType1,如下所示:mymethod(): CustomType1 return someMethodThatReturnsCustomType1AndNull();
我得到一个错误。如何解决这个问题?
最好使用interface
而不是type
,除非您确实需要使用类型。【参考方案2】:
添加到 Erik 的回复中。在他的第二个示例的最后一行,您可以使用“as”关键字,而不是重新声明类型。
let customObj = a.testMethod(false) as CustomType;
所以基本上,如果你有一个函数有多个返回类型,你可以通过使用“as”关键字来指定应该将哪些类型分配给一个变量。
type Person = name: string; age: number | string ;
const employees: Person[] = [
name: "John", age: 42,
name: "April", age: "N/A"
];
const canTakeAlcohol = employees.filter(emp =>
(emp.age as number) > 21;
);
【讨论】:
以上是关于TypeScript 具有相同参数的多种返回类型的主要内容,如果未能解决你的问题,请参考以下文章