繁体   English   中英

如何使泛型对象使用在Typescript中使用一种类型或void的两个函数的函数参数

[英]How to make function argument that is generic object consuming two functions with one type or void in Typescript

我在打字稿中遇到以下情况:

type Matcher<T, U> = {
  First: (arg: T) => U,
  Second: () => U
};

class Main<T> {    
  constructor(private value: T) {
  }

  match<U>(matcher: Matcher<T, U>): U {
    return this.value
      ? matcher.First(this.value)
      : matcher.Second();
  }
}

const main = new Main(10);

const res = main.match({ // there is a problem
  First: v => v + 10,
  Second: () => console.log()
});

因此,我有一个用户必须传递给类实例的match方法的对象。 该对象应包含两个功能: FirstSecond 此函数返回一种类型(例如number )或一种类型+ void (例如number + void )的值,但没有其他值。 不能有string + number类型。

此代码因错误而失败

The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. 
Type argument candidat 'void' is not a valid type argument because it is not a supertype of candidate 'number'.

我理解为什么会发生此错误( U是单一类型,但是函数有两种不同的类型,并且它们无法合并,依此类推),但是如何解决此问题? 我需要:

  • 严格输入,因此不应有any类型
  • 允许仅对两种功能使用一种类型,或者对一种或两种方法都void 不允许使用numberstring作为返回类型。

打字稿类型系统可以吗?

您可以使用联合类型

type Matcher<T, U> = {
    First: (arg: T) => U;
    Second: () => U | void
};

我在第二个函数中添加了void ,但您也可以在第一个函数中添加它。

但是您将需要match方法返回| void | void

match<U>(matcher: Matcher<T, U>): U | void {
    return this.value
        ? matcher.First(this.value)
        : matcher.Second();
}

操场上的代码


编辑

如果我对您的理解正确,那么这可能会有所帮助:

type Matcher<T, U> = {
    First: (arg: T) => U;
    Second: () => U;
};

type MatcherOne<T, U> = {
    First: (arg: T) => void;
    Second: () => U;
};

type MatcherTwo<T, U> = {
    First: (arg: T) => U;
    Second: () => void;
};

class Main<T> {
    constructor(private value: T) { }

    match<U>(matcher: Matcher<T, U>): U;
    match<U>(matcher: MatcherOne<T, U>): U | void;
    match<U>(matcher: MatcherTwo<T, U>): U | void;
    match<U>(matcher: Matcher<T, U> | MatcherOne<T, U> | MatcherTwo<T, U>): U | void {
        return this.value
            ? matcher.First(this.value)
            : matcher.Second();
    }
}

操场上的代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM