Skip to content

Separate Variable Type Check Doesn't Guard Type #37855

Closed
@fishcharlie

Description

@fishcharlie

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions