HelloWorld
HelloWorld

Reputation: 1863

TypeScript complains about non-existent properties in generic function

I am using TypeScript Generics to specify the parameter types a function accepts. As seeing below, Foo and Bar, both have a function called isDirectory but seems to be invalid in the generic function. Can anyone explain me what I am missing here?

class Foo {

    isDirectory(): boolean {
        return true;
    }
}

class Bar {

    isDirectory(): boolean {
        return true;
    }
}

type XYZ = Foo | Bar;

function bas<XYZ>(x: XYZ) {
    !!!!!!!! Property 'isDirectory' does not exist on type 'XYZ'.(2339)
    return x.isDirectory();
}

I know that I can extend the generic type with extends, but why would that be needed in this case? Is there a solution without manually typing an interface?

https://www.typescriptlang.org/play?#code/MYGwhgzhAEBiD29oG8BQrqegSwgEWwCcBTYAF3kIE8AKASgC5oAjREYsAOxQyz5LIBXQtzKFBxANy9MAX1TzUoSDABCYQjxk58RUhWr0mreOy48+-YkJHQxE6X3mKyVAA7FoADQCaALWgAXjhEaAAfaHVCaVQAM0FOcmx4bmZIAB5fPwA+GgAPJiy6CywBYW48gDpcAhJySlo6aVkgA

Upvotes: 0

Views: 110

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 85161

You're using the same name for multiple things. So while you think the XYZ's are all related, they're not. Let me give them unique names so it's clear what is what:

type XYZ = Foo | Bar;

function bas<T>(x: T) {
  return x.isDirectory();
}

The function bas is a generic which accepts any type T. It has no relationship to the XYZ you defined a couple lines earlier. Since T can be anything (say, a number), there's no guarantee it would have an isDirectory function on it.

What you probably meant to do was to restrict T so it can only be an XYZ, or something extending from it:

type XYZ = Foo | Bar;

function bas<T extends XYZ>(x: T) {
  return x.isDirectory();
}

Playground link

Upvotes: 2

Related Questions