Closed
Description
TypeScript Version: 3.8.3
Search Terms:
- separate variable type check guard
- variable type check guard
- variable type guard
Expected behavior:
No errors to be thrown.
Actual behavior:
When using the variable to check the type, the type of item
and itemB
respectively doesn't get narrowed down to the correct type. This works in the first example and it narrows down the type.
This encourages bad practice especially if you are having to repeat the type check over and over. In order to keep code from not becoming repetitive storing that in a variable seems like a much better practice.
Related Issues:
None
Code
class User {
name?: string;
}
type Item = User | string;
const item: Item = Math.random() < .5 ? "Hello World" : new User();
let isItemUser = (item instanceof User);
console.log((item instanceof User) ? item.name : item); // types correct
console.log((isItemUser) ? item.name : item); // types incorrect
//////////////////////////////////////////////////////////////////////////
type ItemB = number | string;
const itemB: ItemB = Math.random() < .5 ? "Hello World" : 2;
let isItemBNumber = (typeof itemB === "number");
console.log((typeof itemB === "number") ? itemB * 100 : itemB); // types correct
console.log((isItemBNumber) ? itemB * 100 : itemB); // types incorrect
Output
"use strict";
class User {
}
const item = Math.random() < .5 ? "Hello World" : new User();
let isItemUser = (item instanceof User);
console.log((item instanceof User) ? item.name : item); // types correct
console.log((isItemUser) ? item.name : item); // types incorrect
const itemB = Math.random() < .5 ? "Hello World" : 2;
let isItemBNumber = (typeof itemB === "number");
console.log((typeof itemB === "number") ? itemB * 100 : itemB); // types correct
console.log((isItemBNumber) ? itemB * 100 : itemB); // types incorrect
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
}
Playground Link: Provided