具有相同参数的 TypeScript 多个返回类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40242426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:25:20  来源:igfitidea点击:

TypeScript multiple return types with identical parameters

typescriptangular2-formstypescript2.0

提问by msanford

Background

背景

Trying to get into the spirit of TypeScript, I am writing fully typed signatures in my Components and Services, which extends to my custom validation functions for angular2 forms.

为了融入 TypeScript 的精神,我在我的组件和服务中编写了完全类型化的签名,这扩展到了我的 angular2 表单的自定义验证函数。

I know that I can overload a function signature, but this requires that the parameters are different for each return type because tsccompiles each signature to a separate function:

我知道我可以重载函数签名,但这要求每个返回类型的参数不同,因为tsc将每个签名编译为单独的函数:

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any { /*common logic*/ };

I also know that I can return a single type (like a Promise) which can itselfbe of multiple sub-types:

我也知道我可以返回单个类型(如 Promise),它本身可以是多个子类型:

private active(): Promise<void|null> { ... }

However, in the context of angular2 custom form validators, a single signature (one parameter of type FormControl) can return two distinct types: an Objectwith form errors, or nullto indicate the control has no errors.

但是,在 angular2 自定义表单验证器的上下文中,单个签名( type 的一个参数FormControl)可以返回两种不同的类型:一个Object带有表单错误,或者null表示控件没有错误。

This, obviously, does not work:

这显然不起作用:

private lowercaseValidator(c: FormControl): null;
private lowercaseValidator(c: FormControl): Object {
    return /[a-z]/g.test(c.value) ? null : { lowercase: this.validationMessages.lowercase };
}

Nor do

也不

private lowercaseValidator(c: FormControl): null|Object {...}
private lowercaseValidator(c: FormControl): <null|Object> {...}

(Interestingly, I get the following errors, rather than something more informative:

(有趣的是,我收到以下错误,而不是提供更多信息:

error TS1110: Type expected.
error TS1005: ':' expected.
error TS1005: ',' expected.
error TS1128: Declaration or statement expected.

)

)

TL;DR

TL; 博士

Am I left simply using

我是否只是使用

private lowercaseValidator(c: FormControl): any { ... }

which would seem to negate the advantage of having type signatures?

这似乎否定了拥有类型签名的优势?

More generally, looking forward to ES6

更一般的,期待 ES6

While this question is inspired by angular2 forms validators, which are handled directly by the framework, so you might not care about declaring the return type, it is still generally-applicable, especially given ES6 constructs like function (a, b, ...others) {}

虽然这个问题的灵感来自 angular2 表单验证器,它由框架直接处理,所以你可能不关心声明返回类型,但它仍然普遍适用,特别是考虑到 ES6 结构,如 function (a, b, ...others) {}

Perhaps it's simply better practice to avoid writing functions that can return multiple types, but it is rather idiomatic, owing to JavaScript's dynamic nature.

也许避免编写可以返回多种类型的函数只是更好的做法,但由于 JavaScript 的动态特性,它相当惯用。

References

参考

采纳答案by Erik Cupal

Ok, this is the right way if you want to have proper types:

好的,如果您想拥有正确的类型,这是正确的方法:

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 };
}

More general example

更一般的例子

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