Tslint: strict-type-predicates: False positive with index types

Created on 22 Jun 2017  ·  3Comments  ·  Source: palantir/tslint

Bug Report

  • __TSLint version__: 5.4.3 5cf7100ad3c7b2fd3be62d94b7b4708460590a97
  • __TypeScript version__: 2.4.0
  • __Running TSLint via__: CLI

Related to: https://github.com/Microsoft/TypeScript/issues/13778

TypeScript code being linted

declare function get<T>(): T;
// index types
{
    get<{ [key: string]: string }>()['foo'] === undefined
    get<{ [key: string]: string }>()['foo'] === null
    get<{ [key: string]: string }>()['foo'] == undefined
    get<{ [key: string]: string }>()['foo'] == null

    get<{ [index: number]: string }>()[0] === undefined
    get<{ [index: number]: string }>()[0] === null
    get<{ [index: number]: string }>()[0] == undefined
    get<{ [index: number]: string }>()[0] == null
}

with tslint.json configuration:

(Using test/rules/strict-type-predicates/strict-null-checks/tsconfig.json)

Actual / Expected behavior

(A is Actual, E is Expected, B is Both)

{
    get<{ [key: string]: string }>()['foo'] === undefined
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
    get<{ [key: string]: string }>()['foo'] === null
B:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
    get<{ [key: string]: string }>()['foo'] == undefined
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
E:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Use '=== undefined' instead.]
    get<{ [key: string]: string }>()['foo'] == null
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
E:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Use '=== undefined' instead.]

    get<{ [index: number]: string }>()[0] === undefined
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
    get<{ [index: number]: string }>()[0] === null
B:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
    get<{ [index: number]: string }>()[0] == undefined
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
E:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Use '=== undefined' instead.]
    get<{ [index: number]: string }>()[0] == null
A:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Expression is always false.]
E:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Use '=== undefined' instead.]
}

(Running example is here: https://github.com/ypresto/tslint/tree/strict-type-predicates-index-type )

External

Most helpful comment

More simple example:

const foo: { [key: string]: string } = {}
if (foo.bar === undefined) {
    // blah
}

will produce

ERROR: /Users/yuya/repo/github.com-private/codetakt/pf-user-admin/client/test.ts[2, 5]: Expression is always false.

but no error is expected.

All 3 comments

More simple example:

const foo: { [key: string]: string } = {}
if (foo.bar === undefined) {
    // blah
}

will produce

ERROR: /Users/yuya/repo/github.com-private/codetakt/pf-user-admin/client/test.ts[2, 5]: Expression is always false.

but no error is expected.

tslint is not the right place to add this kind of special handling. This would require a change in typescript's type inference. https://github.com/Microsoft/TypeScript/issues/13778

If you always check for undefined before using the value, you could also define your index signature to include undefined;

const foo: { [key: string]: string | undefined } = {}

+1 to ajafff - closing as this is a design point of TypeScript.

Was this page helpful?
0 / 5 - 0 ratings