Adding === true
to the expression in the code below breaks TypeScript's type inference. I know that pretty much all style guides recommend not adding === true
, but I would like to know why the two expressions are different.
Can anybody explain this?
function someFunction(element: HTMLElement | null) {
const isAllowed = element !== null;
if (isAllowed) {
// Here, the TypeScript compiler is able to infer that element isn't null...
thisFunctionRequiresAnElement(element);
}
if (isAllowed === true) {
// ... but here, it cannot. Why?
thisFunctionRequiresAnElement(element);
}
}
function thisFunctionRequiresAnElement(element: HTMLElement) {
console.log(element);
}
Link to TypeScript Playground with the code snippet above.
CodePudding user response:
This is a TS 4.4 "feature".
The isAllowed
variable acts like a predicate. This means isAllowed
holds the information that element
is not null
.
By adding a === true
this removes the predicate. You're in fact creating a new boolean from a boolean
expression.
I don't know if we can consider this a bug or a feature.
Playground with TS < 4.4 with both conditions with errors
Edit:
The comment by Anders Hejlsberg (TS creator) nails it :
Narrowing through indirect references occurs only when the conditional expression or discriminant property access is declared in a const variable declaration with no type annotation, and the reference being narrowed is a const variable, a readonly property, or a parameter for which there are no assignments in the function body.