2

Using a generic typed class, I would like some methods to be available ONLY IF generic type is 'string'.

With the following code

class MyClass<T = string> {
  value: T = null;

  setDate(m: Moment) {
    // could be used only if T is string
    value = m ? m.format('YYYY-MM-DD') : null;
  }

}

gives me the error

Argument of type 'string' is not assignable to parameter of type 'T'

which is really clear and totally intended : Moment.format() returns a string. :D

Is there a proper way to make the setDate() method avaible only if T is string ?

By advance, thank you very much.


I know I can fix the problem using m.format('YYYY-MM-DD') as unknown as T but it looks like a workaround, not a real typescript solution.

And I know about Conditional Types but I don't think it could fix my problem. At least, I did not find how to figure it out.

2 Answers 2

3

make function have never arg on incorrect generic

type Moment = {format(s:string):string};

type SimpleEquals<T, V> = [T] extends [V] ? [V] extends [T] ? true : false : false;


class MyClass<T = string> {
  value: T | null = null;

    // could be used only if T is string
  setDate(m: SimpleEquals<T, string> extends true ? Moment : never) {
    this.value = m ? m.format('YYYY-MM-DD') as T : null;
  }
}

declare let m: Moment; 

new MyClass<string>().setDate(m) // ok

new MyClass<number>().setDate() //err
new MyClass<number>().setDate(m) //err

new MyClass<string | number>().setDate() //err
new MyClass<string | number>().setDate(m) //err

new MyClass<'qwe'>().setDate() //err
new MyClass<'qwe'>().setDate(m) //err

Sign up to request clarification or add additional context in comments.

Comments

2

To extend on Dimava's solution, you can set the type of this to never whenever the method should not exist:

class MyClass<T = string> {
  setDate(
    this: T extends string ? MyClass<T> : never,
    m: Moment
  ) {
    ...;
  }
}

The advantage of this strategy is that it works even for methods that don't take any arguments.

Note that this: Type is a special TypeScript syntax to type the this object. The this pseudo-parameter gets removed by TypeScript compiler, so the JavaScript engine never sees it.

1 Comment

I tried using never for conditional return types, but it didn't work as expected. @jo 's approach works perfectly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.