我可以在打字稿中强制执行函数的最后一个参数吗?

时间:2017-06-01 12:21:16

标签: typescript

假设我有一个function type interface我想用来强制执行特定功能的特定签名。

有没有办法强制函数的最后一个参数必须是特定类型?

有没有办法做这样的事情:

interface SomeType { /*...*/ }

/**
 * this is the function type I want to enforce
 * I want the last argument of any `Modifcation` to be `SomeType`
 */
interface Modification {
    (...args: [...firstArgs: any[], lastArgument: SomeType]): void
}

// enforcing `Modification`
const someModification: Modification = (firstParam: string, second: number, third: SomeType) => {
    /*...*/
}

我知道打字稿利用spread syntaxtuple types,但上面的伪代码不起作用。

有办法做到这一点吗?

修改

免责声明:我认为没有办法做我想做的事情,因此这个问题可能不完全是建设性的。

上下文

我有一组类,我想对这些类的特定方法强制执行某种约定。我可以通过声明另一个function type来强制执行某个方法必须符合interface and saying that my class implements that interface

e.g。

interface Convention {(arg0: string, arg1: number): Something}

interface MyClassMethodRequirements {
    myMethod: Convention,
    myOtherMethod: Convention
}

class MyClass implements MyClassMethodRequirements {
    myMethod(a: string, b: number) { return new Something(); }
    myOtherMethod(label: string, aNumber: number) { return new Something(); }
    otherMethod() { return 'just another non-conforming method' }
}

我想要实现的目标:

以上Convention只是一个例子。我想强制执行的是声明为Convention的方法必须具有/考虑这两个参数。

e.g。 (伪代码)

interface NewConvention {(firstArg: any, lastArg?: RequiredType): Something}

interface MyClassMethodRequirements {
    myMethod: NewConvention,
    myOtherMethod: NewConvention
}

class MyClass implements MyClassMethodRequirements {
    myMethod(a: string, b?: RequiredType) { return new Something(); }
    // i want an error here because `myOtherMethod` doesn't list `lastArg: RequiredType` in it's parameters
    myOtherMethod(label: string) { return new Something(); }
    otherMethod() { return 'just another non-conforming method' }
}

对于更多上下文,lastArg的{​​{1}}被认为是可选的覆盖。

同样,我不认为我想要实现的目标是可能的,所以这可能是非建设性的。

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

您可以将第一个参数(类型SomeType)设置为可选,如下所示:

interface SomeType {
    a: number; // just so it's not an empty definition
}

type Modification =
    { (first: SomeType, ...rest: (string | number)[]): void; }
    | { (...rest: (string | number)[]): void; }

// fine
const someModification1: Modification = (firstParam: string, second: number) => {}
const someModification2: Modification = (third: SomeType, firstParam: string, second: number) => { }

// error
const someModification3: Modification = (firstParam: string, second: number, third: SomeType) => { }

请注意,如果您使用any[]作为参数,那么这也将涵盖SomeType arg。

答案 1 :(得分:1)

如果您知道参数的最大数量,则可以根据需要执行尽可能多的重载。

type Modification =
    { (arg1: any, lastArgument: SomeType): void } |
    { (arg1: any, arg2: any, lastArgument: SomeType): void } |
    { (arg1: any, arg2: any, arg3: any, lastArgument: SomeType): void };