ziv
ziv

Reputation: 3870

typescript generics assign empty object

this is what I want to achieve:

interface IFoo { ... }
function extendWithFoo<T extends {}>(x: T = {}): T & IFoo {
 ...
}

I'm getting error TS2322: Type '{}' is not assignable to type 'T'.

Is there a way to do this?

Upvotes: 6

Views: 8852

Answers (2)

Matthew Layton
Matthew Layton

Reputation: 42260

In addition to Nitzan Tomer's suggestion, you can also introduce a type to restrict the input to object literals only

type ObjectLiteral = { [key: string]: any };

interface IFoo {
    resultHasFoo(): void; 
}

function extendWithFoo<T extends ObjectLiteral>(x: T = {} as T): T & IFoo {
    return x as T & IFoo;
}

extendWithFoo(false); // error!

extendWithFoo(123); // error!

var p = extendWithFoo({
    test: "one"
});

p.resultHasFoo(); // works!

Take a look at my related post... JavaScript to TypeScript: Intellisense and dynamic members

Upvotes: 0

Nitzan Tomer
Nitzan Tomer

Reputation: 164139

You can do this:

function extendWithFoo<T extends {}>(x: T = {} as T): T & IFoo {
    ...
}

But using empty objects is problematic, as it accepts everything:

extendWithFoo(3); // ok
extendWithFoo("string"); // ok
extendWithFoo(true); // ok
extendWithFoo({}); // ok
extendWithFoo({ key: "value" }); // ok
extendWithFoo(new Array()); // ok

So my recommendation is to use something more specific.
In any case, you don't really need it, you can just:

function extendWithFoo<T>(x: T = {} as T): T & IFoo {
    ...
}

Which gives you the same thing.

Upvotes: 1

Related Questions