如何避免在Typescript中的子类中重新声明类方法参数类型

dgiusagp  于 2023-11-20  发布在  TypeScript
关注(0)|答案(1)|浏览(215)

我有一个子类,它在不同的文件中扩展了一个抽象超类。下面的代码在implementation.ts中没有通过doStrangeThing()的TS类型检查,因为我需要重新声明参数类型(字符串,IComplexOptions)。我希望避免额外的导入和冗长。有人能指出如何做到这一点吗(如果可能的话)?
编译器应该从超类中推断出方法签名,这似乎是很直观的,特别是如果超类是抽象的,或者至少在缺少的情况下将其作为默认值。有没有什么方法可以做到这一点(尽管尝试重载方法或联合类型等复杂性),或者至少有某种方法可以提取参数,或者有某种方法可以提示编译器从超类继承签名?

//
// baseClasses.ts
//
import {IComplexOptions} from './foo';

abstract class Animal {
  abstract name: string;
  abstract doStrangeThing( action:string, options:IComplexOptions ):void;
}

//
// implementation.ts
//
import {Animal} from './baseClasses';

class Rhino extends Animal {
  name="Rhino";
  doStrangeThing(action,options){  // <== TS error here, implicit 'any'

  }
}

字符串

uajslkp6

uajslkp61#

实际上没有办法避免重新声明参数的类型,因为Typescript实现了结构继承。
作为一种解决方法,您可以使用Parameters实用程序类型从另一个接口提取参数。当使用单个对象作为函数参数(相对于位置参数)并且您的方法的参数可能经常更改时,这很有用。
举例来说:

interface Foo {
  method(args: { arg1: string, arg2: number}): void;
}

class Bar implements Foo {
  method({ arg1, arg2 }: Parameters<Foo['method']>[0]): void {
    // arg1 and arg2 types will be correctly inferred
  }
}

字符串
如果你有几个方法需要重新声明,你可以为一个特定的类创建你自己的实用程序类型:

interface Foo {
  method(args: { arg1: string, arg2: number}): void;
}

type FooArgs<Method extends keyof Foo> = Parameters<Foo[Method]>[0];

class Bar implements Foo {
  method({ arg1, arg2 }: FooArgs<'method'>): void {
    // arg1 and arg2 types will be correctly inferred
  }
}

相关问题