Why do I not get a compiler error when I have the TransitionDefinition interface defined with:
export interface State {
name: string
}
export type StateResolveFunc = (fsm: string) => State[]
export interface TransitionDefinition {
from: State | State[] | StateResolveFunc
}
and then create an object like:
const t0: TransitionDefinition = {
from: (fsm) => 'startState' // Why do I not get a compiler error?
}
I should not be allowed to return a string here! When I just have the function type and not a union, the compiler complains as expected.
Typescript example using typescript 3.1.1
So the reason behind this behavior is that all functions have a name property. Because of that, any function will be assignable to State.
Since you likely didn't want anything callable to be assigned to State, you can ensure that functions are not assignable to it by including an optional apply field with type never. So something like:
interface State {
name: string;
apply?: never; // Ensures functions are not assignable to this interface.
}
This works because all functions have an apply method, but the type of that method isn't never, which means it can't be assigned to State. This same trick can be used with any of the common function properties, like call or bind, in place of apply.
Anyway, using that trick, your snippet:
export interface State {
name: string;
apply?: never;
}
export type StateResolveFunc = (fsm: string) => State[]
export interface TransitionDefinition {
from: State | State[] | StateResolveFunc
}
const t0: TransitionDefinition = {
from: (fsm) => 'startState' // Now produces an error
}
Now creates an error:
Type 'string' is not assignable to type 'State[]'.
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