在 Typescript 中声明一个委托类型
Posted
技术标签:
【中文标题】在 Typescript 中声明一个委托类型【英文标题】:Declare a delegate type in Typescript 【发布时间】:2013-12-17 02:28:10 【问题描述】:来自 C# 背景,我想创建一个定义函数签名的数据类型。在 C# 中,这是一个 delegate
声明如下:
delegate void Greeter (string message);
public class Foo
public void SayHi (Greeter g)
g("Hi!");
现在,我想在 Typescript 中实现类似的功能。我知道 Typescript 没有委托类型,而只有 lambdas。我想出了这样的事情:
class Foo
SayHi (greeter: (msg: String) => void)
greeter('Hi!');
虽然这可行,但我想多次重复使用方法签名(msg:String) => void
,并认为创建自定义类型会更简洁——比如 C# 中的委托。
有什么想法可以做到这一点吗?
【问题讨论】:
Are strongly-typed functions as parameters possible in TypeScript?的可能重复 【参考方案1】:您可以使用type alias 创建类似委托的东西:
type MyDelegate = (input: string) => void;
定义函数指针的类型名称,就像在 C# 中的委托一样。以下示例将其与泛型类型参数结合使用:
type Predicate<T> = (item: T) => boolean;
export class List<T> extends Array<T>
constructor(...items: T[])
super();
for(let i of items || [])
this.push(i);
public hasAny(predicate?: Predicate<T>): boolean
predicate = predicate || (i => true)
for(let item of this)
if(predicate(item)) return true;
return false;
【讨论】:
仅供参考:这些称为类型别名。【参考方案2】:五年后,很多很多 TS 版本我发现自己使用更简单的 type
定义来声明函数类型:
type Greeter = (msg: string) => void;
const someGreeter: Greeter = (msg: string) => `Hi there with $msg`;
【讨论】:
请注意,第 2 行的: string
不是必需的;可以根据分配给Greeter
来推断类型。【参考方案3】:
我现在发布和使用@steelbreeze/delegate;与 C# 委托相比,它有一些限制,因为它是不可变的,但在其他方面运行良好(调用时返回所有调用函数的结果)。
它可以让你编写如下代码:
import create as delegate from "@steelbreeze/delegate";
function world(s: string)
console.log(s + " world");
const one = delegate(s => console.log(s + " Hello world"));
const two = delegate(s => console.log(s + " Hello"), world);
one("A");
two("B");
delegate(one, two)("C");
【讨论】:
【参考方案4】:可调用表达式的类型定义(这是一个草稿,对人类来说……不是 BNF 或任何正式的东西):
callableType: (paramsDef) => returnType
paramsDef: MULTIPLE paramDef SEPARATED BY ,
paramDef: EITHER paramName: paramType
OR optionalParamName?: paramTypeWhenDefined
OR ...manyParamName: eachParamType[]
例子:
var func = something as ((...x: any[]) => any);
那么你可以:
var result = func("a", "b", 2);
【讨论】:
【参考方案5】:在 TypeScript 中,接口可以有调用签名。在您的示例中,您可以这样声明:
interface Greeter
(message: string): void;
function sayHi(greeter: Greeter)
greeter('Hello!');
sayHi((msg) => console.log(msg)); // msg is inferred as string
【讨论】:
不太一样,但我们拥有最好的。我只是讨厌在匿名强类型函数应该做的时候必须到处声明接口。 不确定你的意思——你也可以有匿名函数类型。 我想声明一个接收回调委托的函数,例如。 C# 中的 Funcfunction foo(x: (n: number) => string) console.log(x(3));
,或等效的function foo(x: (n: number): string; ) ...
如何声明和导出作为 Greeter
实例的函数,以便在将欢迎函数导入不同文件时获得正确的智能感知?以上是关于在 Typescript 中声明一个委托类型的主要内容,如果未能解决你的问题,请参考以下文章