Skip to content

TS2.9 narrows MyType|undefined to undefined (regression from 2.8) #25268

Closed
@webmaster128

Description

@webmaster128

TypeScript Version:

  • typescript@2.8.4 ok
  • typescript@2.9.2 bug
  • typescript@3.0.0-dev.20180626 bug

Search Terms:

Code

declare const AddressSymbol: unique symbol;
type AddressString = typeof AddressSymbol & string;

function printout(data: AddressString | undefined) {
  console.log(data); // type of `data` is always undefined since TS 2.9
}

printout(undefined); // ok

const a = "foo" as AddressString;
printout(a); // broken since TS 2.9

Expected behavior: the code compiles

Actual behavior: since TypeScript 2.9, the compilations fails with:

$ ./node_modules/typescript/bin/tsc example.ts
example.ts:11:10 - error TS2345: Argument of type 'AddressString' is not assignable to parameter of type 'undefined'.

11 printout(a); // broken in TS 2.9
            ~

Playground Link: http://www.typescriptlang.org/play/#src=declare%20const%20AddressSymbol%3A%20unique%20symbol%3B%0D%0Atype%20AddressString%20%3D%20typeof%20AddressSymbol%20%26%20string%3B%0D%0A%0D%0Afunction%20printout(data%3A%20AddressString%20%7C%20undefined)%20%7B%0D%0A%20%20console.log(data)%3B%0D%0A%7D%0D%0A%0D%0Aprintout(undefined)%3B%20%2F%2F%20ok%0D%0A%0D%0Aconst%20a%20%3D%20%22foo%22%20as%20AddressString%3B%0D%0Aprintout(a)%3B%20%2F%2F%20broken%20since%20TS%202.9

Related Issues: #25179

Activity

ahejlsberg

ahejlsberg commented on Jun 27, 2018

@ahejlsberg
Member

This is working as intended and is an effect of #23672. The type checker now more effectively removes intersection types with empty value domains (such as symbol & string) when they're included in union types. Since it isn't possible to construct values that are simultaneously symbol and string, the type symbol & string is effectively the same as never and the type checker treats it accordingly.

webmaster128

webmaster128 commented on Jun 27, 2018

@webmaster128
Author

Thank you very much for the explanation, @ahejlsberg! Makes sense so far. We only cast to those things in order to get strict string aliases and they can indeed not be constructed.

But shouldn't a be of type never too in the following lines?

declare const AddressSymbol: unique symbol;
type AddressString = typeof AddressSymbol & string;
const a = "foo" as AddressString;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @webmaster128@ahejlsberg

        Issue actions

          TS2.9 narrows `MyType|undefined` to undefined (regression from 2.8) · Issue #25268 · microsoft/TypeScript