Tslint: Custom Typeguard causes "Expression is always true."

Created on 17 Jan 2018  路  1Comment  路  Source: palantir/tslint

Bug Report

  • Node v8.9.4
  • TypeScript v2.6.2
  • TSLint v5.9.1
  • tslint-config-standard v7.0.0
  • Running TSLint via: CLI: tslint --project tsconfig.json --config tslint.json

TypeScript code being linted

interface Animal {
  move: number,
}

interface Bird extends Animal {
  fly: number,
}

function isBird (animal: Animal): animal is Bird {
  return (animal as Bird).fly !== undefined
}

Also:

function isBird (animal: Animal | Bird): animal is Bird {
  return (animal as Bird).fly !== undefined
}

NB: The minimum viable example above is derived from an actual use case using LeafletEvent and LeafletMouseEvent from Leaflet. Types defined at DefinitelyTyped.

tslint.json configuration:

{
  "rules": {
    "strict-type-predicates": true
  }
}

tsconfig.json config:

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowJs": false,
    "moduleResolution": "node",
    "noUnusedLocals": true,
    "sourceMap": true,
    "strict": true
  },
  "exclude": [
    "node_modules"
  ],
  "include": [
    "./src/frontend/**/*",
    "./webpack.config.ts"
  ]
}

Actual behavior

$ tslint --project tsconfig.json --config tslint.json

WARNING: /Users/andrew/Development/poc/src/frontend/test.ts[10, 10]: Expression is always true.

Expected behavior

I'm still quite new to TypeScript, but given the Advanced Types documentation, I would have expected no error. Apologies if I've misunderstood how this works.

I note similarities with #3222 .

If I remove the type cast, TSLint ceases to complain, but TypeScript begins to throw compilation errors.

// results in: Property 'fly' does not exist on type 'Animal | Bird'. Property 'fly' does not exist on type 'Animal'.
function isBird (animal: Animal | Bird): animal is Bird {
  return animal.fly !== undefined
}
Question

Most helpful comment

This is working as intended. By asserting animal as Bird you tell TypeScript that animal.fly is always a number and never undefined. That's why the rule complains.

You can fix this by using animal as Partial<Bird>.

>All comments

This is working as intended. By asserting animal as Bird you tell TypeScript that animal.fly is always a number and never undefined. That's why the rule complains.

You can fix this by using animal as Partial<Bird>.

Was this page helpful?
0 / 5 - 0 ratings