By and large, TypeScript is an incredible tool that I'm very grateful for, but sometimes it really makes me want to tear my hair out.
TypeScript 3.1 introduced a breaking change involving narrowing functions that I have no idea how to work around.
Here's one attempt to make an unconstrained generic into something that's vaguely constrained: I want to define a type T
in which we don't know what properties it has, but we want to make sure that any properties it does have are booleans.
type ObjWithBooleanValues = {
[key: string]: boolean;
};
function blarg<T extends ObjWithBooleanValues>(thing: T|((arg: string) => void)): boolean {
if (typeof(thing) === 'function') {
// Yay, TS 3.1 actually is OK with this, unlike if T was unconstrained.
thing('awge');
return true;
} else {
// Except now TS thinks that keys which don't exist are actually booleans. :(
return thing.totallyNonexistentPropertyThatBizarrelyTypechecks;
}
}
const notActuallyABooleanEvenThoughTypescriptThinksItIs = blarg({ hello: true });
I have no idea how to convince TypeScript that T
is constrained to anything that either isn't a function, or is JSON-serializable, or something else that doesn't also cause the type to do really weird things.
Admittedly this isn't really TypeScript's fault, but the insanity of web development is really getting to me.
Your
thing.totallyNonexistentPropertyThatBizarrelyTypechecks
is not bizarre, it compiles because your genericT
extends anObjWithBooleanValues
which accepts any string.