Skip to content

Type guard not applied based on indexed access with string literal #26232

Closed
@dalen

Description

@dalen

TypeScript Version: 3.1.0-dev.20180804

Search Terms:
dash, bracket

Code

Very similar to documentation example code, but with a discriminant containing a dash. Likely not because of the dash itself, but because the lookup is using s['kind-of'] instead of s.kind.

interface Square {
  'kind-of': 'square';
  size: number;
}

interface Rectangle {
  'kind-of': 'rectangle';
  width: number;
  height: number;
}
type Shape = Square | Rectangle;

function area(s: Shape): number {
  if (s['kind-of'] === 'square') {
    // Now TypeScript *knows* that `s` must be a square ;)
    // So you can use its members safely :)
    return s.size * s.size;
  } else {
    // Wasn't a square? So TypeScript will figure out that it must be a Rectangle ;)
    // So you can use its members safely :)
    return s.width * s.height;
  }
}

Expected behavior:

No errors

Actual behavior:

test.ts:17:14 - error TS2339: Property 'size' does not exist on type 'Shape'.
  Property 'size' does not exist on type 'Rectangle'.

17     return s.size * s.size;
                ~~~~

test.ts:17:23 - error TS2339: Property 'size' does not exist on type 'Shape'.
  Property 'size' does not exist on type 'Rectangle'.

17     return s.size * s.size;
                         ~~~~

test.ts:21:14 - error TS2339: Property 'width' does not exist on type 'Shape'.
  Property 'width' does not exist on type 'Square'.

21     return s.width * s.height;
                ~~~~~

test.ts:21:24 - error TS2339: Property 'height' does not exist on type 'Shape'.
  Property 'height' does not exist on type 'Square'.

21     return s.width * s.height;
                          ~~~~~~

My real world use case is to check type of AWS Cloudwatch event using the detail-type field on the event, so can't just change the name to get around the restriction easily.

Metadata

Metadata

Assignees

Labels

Add a FlagAny problem can be solved by flags, except for the problem of having too many flagsBugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions