Typescript: Cast Method of a class to a certain type

Created on 16 Jul 2020  ·  2Comments  ·  Source: microsoft/TypeScript

Search Terms

casting
type
interface
method
function
parameters
inference
class

Suggestion


Currently, it is impossible to infer the parameters and the return types of a method of a class using a type

The goal is to be able to declare a method without repeating the param types and the return type. I used typescript Type for that.

But there is currently no way to do this without changing the compiled javascript code.

type IBar = (x:number, y: number)=>number;

I tried

type IBar = (x:number, y: number)=>number;
class Foo {
    sum:IBar=(x,y)=>{
        return x+y;
    }
}

BUT unfortunately, this changes the javascript code compiled into:

class Foo {
    constructor() {
        this.sum = (x, y) => {
            return x + y;
        };
    }
}

I am looking for something that compiles into:

class Foo {
    sum(x, y) {
        return x + y;
    }
}

Another option currently is to declare an interface and implement it on the class like so:

interface IBar { sum(x: number, y: number): number; }

class Foo implements IBar {
    public sum(x: number, y: number): number {
        return x + y;
    }
}

HOWEVER, this approach would bnd the method name to only sum . What if I want to use the same method type with a different name like divide or multiply

Use Cases


It will be used like this

class Foo {
    sum(x,y){
        return x+y;
    } as IBar
}

Examples

class Foo {
    sum(x,y){
        return x+y;
    } as IBar
}

or

class Foo {
    divide(x,y){
        return x+y;
    } as IBar
}

or

class Foo {
    multiply(x,y){
        return x+y;
    } as IBar
}

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.
  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
Awaiting More Feedback Suggestion

Most helpful comment

What do we think of this form?

type BinaryOperator<T> = (x: T, y: T) => T

class Foo {
    // Notice the lack of "="
    sum: BinaryOperator<number> (x, y) {
      return x+y;
    }
}

This would be a nice parallel to usual variable type declaration. I feel like the as X expression is an assertion instead of a declaration. Like, if you were to use it on an arrow function:

const sum = ((x,y,z) => false) as BinaryOperator<number> // sum is (number,number) => number

const sum: BinaryOperator<number> = ((x,y,z) => false) //error!

I do like the idea of declaring the typing for methods though.

All 2 comments

What do we think of this form?

type BinaryOperator<T> = (x: T, y: T) => T

class Foo {
    // Notice the lack of "="
    sum: BinaryOperator<number> (x, y) {
      return x+y;
    }
}

This would be a nice parallel to usual variable type declaration. I feel like the as X expression is an assertion instead of a declaration. Like, if you were to use it on an arrow function:

const sum = ((x,y,z) => false) as BinaryOperator<number> // sum is (number,number) => number

const sum: BinaryOperator<number> = ((x,y,z) => false) //error!

I do like the idea of declaring the typing for methods though.

+1 on this
It would be very useful

class Foo {
    // Notice the lack of "="
    sum: BinaryOperator<number> (x, y) {
      return x+y;
    }
}

This solution feels good to me 👍🏻


Note that I would also expect to work with (or as an alternative) implements

interface IFoo {
  sum: BinaryOperator<number>
}

class Foo implements IFoo {
  sum() (x, y) {
      return x+y;
    }
}
Was this page helpful?
0 / 5 - 0 ratings