Adam Venturella Adam Venturella - 2 months ago 9
TypeScript Question

How to properly assign correlated types to methods

I'm trying to better understand the type inferance rules and I have a contrived example that is stumping me:

The setup:

interface Model{
label?: string;
}

interface View<T>{
cid?: string;
model?: T;
}

class Foo {
findWithModel<TModel extends Model, TView extends View<TModel>>(value: TModel): TView;
findWithModel(value: string): any {
return {cid: "2"};
}
}

class AModel implements Model{
constructor(public label: string){}
}

class AView<T extends Model> implements View<T>{
cid = "1";
model = null;
}

let f = new Foo();
let model = new AModel("test");


So I have an overload,
findWithModel
and in one case it's returning
any
and the other it should effectively be a returning
SomeView<SomeModel>
the issue comes in as follows:

let trial1 = f.findWithModel<AView<AModel>, AModel>(model);
let trial2: AView<AModel> = f.findWithModel(model);


So
trial1
, that works, but obviously that's pretty verbose to the point of why bother. Seems like extra work to pass
AModel
2x

So I assumed, you know I should just be able to provide the type info on the result declaration,
trial2
but typescript then sees that as:

Foo.findWithModel<AModel, {}>(value: AModel): {}


This obviously fails:

Property 'cid' is missing in type '{}'


Is this even possible to pull off without the overly verbose invocation where I pass the
AModel
2x?

Answer

If you don't mind getting back View<T> instead of the more specific type which you pass in the generic constraint, then you can just do:

findWithModel<TModel extends Model>(value: TModel): View<TModel> {
    ...
}

let trial1 = f.findWithModel(model); // type of trail1 is View<AModel>
Comments