typescript - Union-typ med objekt eller funktion kontrollerar inte funktionssignaturen korrekt
Varför får jag inte ett kompileringsfel när jag har TransitionDefinition-gränssnittet definierat med:
export interface State {
name: string
}
export type StateResolveFunc = (fsm: string) => State[]
export interface TransitionDefinition {
from: State | State[] | StateResolveFunc
}
och sedan skapa ett objekt som:
const t0: TransitionDefinition = {
from: (fsm) => 'startState' // Why do I not get a compiler error?
}
Jag borde inte tillåtas att returnera en sträng här! När jag bara har funktionstypen och inte en union, klagar kompilatorn som förväntat.
Typescript-exempel som använder typescript 3.1.1
Svar #1
Så anledningen bakom detta beteende är att alla funktioner har en name-egenskap. På grund av det kommer vilken funktion som helst att kunna tilldelas till State.
Eftersom du troligen inte ville att något anropbart skulle tilldelas State, kan du säkerställa att funktioner inte kan tilldelas den genom att inkludera ett valfritt apply-fält med typen never. Så något som:
interface State {
name: string;
apply?: never; // Ensures functions are not assignable to this interface.
}
Detta fungerar eftersom alla funktioner har en apply-metod, men typen av den metoden är inte never, vilket betyder att den inte kan tilldelas till State. Samma trick kan användas med vilken som helst av de vanliga funktions-egenskaperna, som call eller bind, istället för apply.
Hur som helst, genom att använda det tricket, din kodsnutt:
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
}
Skapar nu ett fel:
Typen 'string' kan inte tilldelas typen 'State[]'.
