У меня есть следующие типы:
type State<C, S> = {
onEnter?: (context: C) => void;
onExit?: (context: C) => void;
transitions?: (context: C) => S | undefined;
};
class FSM<C, S extends Record<keyof S, State<C, keyof S>>> {
constructor(public readonly states: S, public readonly context: C) {
/* ... */
}
}
Если я создаю их экземпляры следующим образом:
const context = { foo: "bar" };
const f = new FSM(
{
a: { transitions: c => "b" }, // ERROR: c is implicitly any
b: { transitions: c => "a" } // ERROR: c is implicitly any
},
context
);
Компилятор жалуется, что c
неявно any
и не может разрешите тип S
(он выглядит как never
). Явный ввод c
устраняет проблему, например:
a: { transitions: (c:typeof context) => "b" },
b: { transitions: (c:typeof context) => "a" }
Почему это так? Разве он не может быть в состоянии вывести C
из параметра context
конструктора FSM
?
Wild Ass Guess : соответствует ли порядок параметров в FSM
конструктор имеет значение? Неужели он сначала пытается разрешить тип states
и еще не знает о типе context
? Если да, то есть ли способ помочь компилятору «заглянуть в будущее»?
ПРИМЕЧАНИЕ : Еще одна вещь, которую мне трудно понять по этому поводу, это то, что если я явно наберу c
с случайный тип - например, transitions: (c:number)=>"a";
компилятор жалуется, что c
не соответствует типу контекста. Таким образом, компилятор знает, что это за тип c
, но ему нужно, чтобы я показал, что я тоже это знаю?