Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
webmaster128 opened this issue Jun 27, 2018 · 2 comments
Closed

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

webmaster128 opened this issue Jun 27, 2018 · 2 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@webmaster128
Copy link

webmaster128 commented Jun 27, 2018

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

@ahejlsberg
Copy link
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.

@ahejlsberg ahejlsberg added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jun 27, 2018
@webmaster128
Copy link
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
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants