I'm defining an interface with generic function like:
export interface IState {
send: <I, E>(message: I, callback?: (e: E) => void) => IState;
}
It works fine for classes with more than one signatures:
class Left implements IState {
send(m: 'go-on', cb?: (e: never) => void): Left;
send(m: 'turn-right', cb?: (e: never) => void): Right;
send(m: 'go-on' | 'turn-right', cb?: any) {
return m === 'go-on' ? new Left() : new Right();
}
}
class Right implements IState {
send(m: 'go-on', cb?: (e: never) => void): Right;
send(m: 'turn-left', cb?: (e: never) => void): Left;
send(m: 'go-on' | 'turn-left', cb?: any) {
return m === 'go-on' ? new Right() : new Left();
}
}
type Both = Left | Right;
function test(l: Both) {
if (l instanceof Left) {
l.send('turn-right')
.send('turn-left')
.send('turn-right')
.send('turn-left');
}
const l2 = new Left();
l2.send('go-on')
.send('turn-right')
.send('turn-left');
l2.send('turn-right').send('turn-left');
}
However when I want to define an IState with only one send signature, I got compile errors:
class CountState implements IState {
constructor(public readonly data: number) {}
// send(m: 'inc', cb?: (e: number) => void): CountState;
// send(m: 'inc', cb?: (e: number) => void): CountState;
send(m: 'inc', cb?: (e: number) => void): CountState {
const result = this.data + 1;
if (cb !== undefined) {
cb(result);
}
return new CountState(this.data + 1);
}
}
Error on send method:
Property 'send' in type 'CountState' is not assignable to the same property in base type 'IState'. Type '(m: "inc", cb?: ((e: number) => void) | undefined) => CountState' is not assignable to type '(message: I, callback?: ((e: E) => void) | undefined) => IState'. Types of parameters 'm' and 'message' are incompatible. Type 'I' is not assignable to type '"inc"'.ts(2416)
If I add those two comments lines, such that
class CountState implements IState {
constructor(public readonly data: number) {}
send(m: 'inc', cb?: (e: number) => void): CountState;
send(m: 'inc', cb?: (e: number) => void): CountState;
send(m: 'inc', cb?: (e: number) => void): CountState {
const result = this.data + 1;
if (cb !== undefined) {
cb(result);
}
return new CountState(this.data + 1);
}
}
It compiles fine, but it looks really strange. How can I fix this?