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

Property does not exist on never with empty interface and type guard #14059

Closed
xealot opened this Issue Feb 14, 2017 · 3 comments

Comments

Projects
None yet
3 participants
@xealot

xealot commented Feb 14, 2017

TypeScript Version: 2.1.1

Code

export interface Record {
    kind: string;
    name: string;
}

export interface UsefulType extends Record {}

export function isUseful(c: Record): c is UsefulType {
    return c.kind === "one";
}

export function doThing(record: Record) {
    if (isUseful(record)) {
        return null;
    }

    console.log(record.name);
    return record;
}

Expected behavior:

No errors.

Actual behavior:

record is converted to never after the if.

This seems to be because of the empty interface declaration. While I know it's not really that useful to declare an empty interface, it's useful for us to implicitly document this particular library and it really shouldn't cause an error.

If you add a member of any kind to the interface, the error clears up.

Playground Link

@mhegazy

This comment has been minimized.

Contributor

mhegazy commented Feb 14, 2017

Types in TypeScript are structural. The narrowing with the user-defined type guard will remove anything that looks like UsefulType, which happens to be the same as Record since it does not add any new properties. Removing type Record, you are left with never.

@xealot

This comment has been minimized.

xealot commented Feb 14, 2017

👍

@xealot xealot closed this Feb 14, 2017

@pranavanmaru

This comment has been minimized.

pranavanmaru commented Jul 31, 2017

function isBook(text: Book | Magazine): text is Book {
    return (<Book>text).author !== undefined;
}

let readingMaterial: Book | Magazine = util.GetAllBooks()[0];

if (isBook(readingMaterial)) {
    console.log(`The book's author is ${readingMaterial.author}`);
}

else {
    console.log(`The magazine's publisher is ${readingMaterial.publisher}`);
}

TS2339 Property 'publisher' does not exist on type 'never'.

in my case though, I have a type that I'm left with after removing one type. Ideally this should make typescript narrow it down to Magazin in the else block. However that isn't happening.

@Microsoft Microsoft locked and limited conversation to collaborators Jun 19, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.