javascript - "Det här uttrycket kan inte anropas" i Typescript med typsmala
Jag definierar en funktion med samma signatur som Reacts useState:
declare function useState<S>(
initialState: S | (() => S),
): [S, React.Dispatch<React.SetStateAction<S>>];
Här är en del av funktionen:
function foo<T>(initialState: T | (() => T)) {
typeof initialState === 'function' ? initialState() : initialState;
}
Jag får det här felet:
This expression is not callable.
Not all constituents of type '(() => T) | (T & Function)' are callable.
Type 'T & Function' has no call signatures.(2349)
Betyder inte T & Function att T är en funktion, så den skulle kunna anropas? Hur kan jag fixa detta utan tvingade typomvandlingar?
Svar #1
Typen kan framgångsrikt avgränsas med initialState instanceof Function:
function foo<T>(initialState: T | (() => T)) {
initialState instanceof Function ? initialState() : initialState;
}
Redigera: intressant nog kompilerar detta, men det kommer att misslyckas för vissa kantfall. Till exempel, om initialState är Object.create(Function.prototype). Detta är en instans av Function men är inte anropbar.
Svar #2
Det enklaste sättet skulle vara att säga till kompilatorn att initialState är en funktion när typeof initialState är 'function'.
function foo<T>(initialState: T | (() => T)) {
if (isFunction(initialState)) {
initialState();
} else {
initialState;
}
}
function isFunction<T>(f: T | (() => T)): f is (() => T) {
return typeof f === 'function';
}
