Let's say I have a function type interface that I want to use to enforce a certain signature of particular functions.
Is there a way to enforce that the last argument of a function must be a particular type?
Is there a way to do something like this:
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) => {
/*...*/
}
I know that typescript utilizes use the spread syntax and tuple types but the psuedo-code above doesn't work.
Is there a way to do this?
Edit:
Disclaimer: I don't think there's a way to do what I want and this question may not be completely constructive as a result.
Context:
I have a set of classes and I want to enforce a certain convention on particular methods of those classes. I can enforce that a certain method must conform to a function type by declaring another 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' }
}
What I want to achieve:
The Convention
above is just an example. What I want to enforce is that a method asserted to be a Convention
must have/consider both parameters.
e.g. (pseudo-code)
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' }
}
for some more context, the lastArg
of NewConvention
is suppose to be an optional override.
Again, I don't think what I'm trying to achieve is possible so this may be unconstructive.
Thanks for your help :)
If you know the maximum number of parameters, you could do as many overloads as needed.
type Modification =
{ (arg1: any, lastArgument: SomeType): void } |
{ (arg1: any, arg2: any, lastArgument: SomeType): void } |
{ (arg1: any, arg2: any, arg3: any, lastArgument: SomeType): void };
You can have the first argument (of type SomeType
) as optional like so:
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) => { }
Notice that if you use any[]
for the args then that will cover the SomeType
arg as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With