方法之间的类型约束

时间:2018-11-27 21:06:39

标签: typescript generics

是否可以在方法之间创建具有类型约束的类/对象?

abstract class Test<T>{
  abstract method1(): T
  abstract method2 (arg: T):any
}

我想要的是method2的参数与method1的返回类型相同的类型-如果类型不同,则应该得到类型错误。类型本身并不重要。

我通过使用泛型类实现了这一点,但是我需要提前传递类型,这对我来说似乎是虚假的和不必要的。

  1. 是否有一种方法可以执行此操作而无需事先指定类型或没有泛型类?
  2. 其他问题-是否可以引用其他方法的类和/或返回类型?是method2(arg: ReturnType<this.method1>):any还是method2(arg: typeof this.method1):any的一行?

2 个答案:

答案 0 :(得分:0)

解决方案

使用ReturnType<Test['method1']>代替ReturnType<this.method1>

class RandomClass{
  methodX(): number {
    return 1;
  }
}

let randomFunction = function() : boolean {
  return true;
}

class TestClass{
  method1(): string {
    return '';
  };
  method2 (arg: ReturnType<TestClass['method1']>): any {
    return null;
  }
  method3 (arg: ReturnType<RandomClass['methodX']>): any {
    return null;
  }
  method4 (arg: ReturnType<typeof randomFunction>): any {
    return null;
  }
}

let test = new TestClass();

test.method2('asd'); // OK
test.method2(2); // TS compilation error. Expected string

test.method3(5); // OK
test.method3('asdf'); // TS compilation error. Expected number

test.method4(true); // OK
test.method4('asd'); // TS compilation error. Expected boolean

使用stackblitz中的TS错误检查此代码。

注意: ReturnType<>从TypeScript 2.8+起有效。

答案 1 :(得分:0)

我假设您希望能够为任意T定义函数的链接对,否则您将只编写具有具体类型的函数,对吗?我认为以任何方式对其进行切片,都需要在某个地方使用通用类型参数,以将第一个函数的返回类型与第二个函数的参数联系起来。

那又怎么样:

interface Linked<T> {
    (): T;
    method2: (arg: T) => any;
}

const method1String: Linked<string> = () => "foo";
method1String.method2 = arg => arg.length;

尝试一下,它有两个不错的属性:

  • 如果没有method2属性,则会出现编译器错误。
  • method2的参数类型已正确推断,如果尝试以其他方式键入它,则会出现编译器错误。

也就是说,我认为了解这里的上下文会很有用。大概这些功能打算以某种方式一起使用,那么是什么阻止您简单地以这种方式约束它们呢?

function doSomethingWithLinkedFunctions<T>(function1: () => T, function2: (arg: T) => any) {
}

这样的好处是不需要笨拙的数据类型,并且能够从T推断function1

另一种选择,以防一对功能需要保持在一起:

type Linked<T> = [() => T, (arg: T) => any];

function doSomething([func1, func2]: Linked<string>) {
}