#Can't figure out the difference between these 2 snippets

8 messages · Page 1 of 1 (latest)

reef bluff
#

Hi all! I would appreciate some clearance on my following concern. I'm pretty new and currently studying generics and trying to figure out why in this snippet, cache recognizes the 'save' property:

type CacheHost = {
  save: (a: any) => void;
}

function addObjectToCache<Type, Cache extends CacheHost>(obj: Type, cache: Cache): Cache {
  cache.save(obj);
  return cache;
}

But it does not if I write it like this, when it clearly has 'save' as a property anyway??:

type CacheHost = {
  save: (a: any) => void;
}

function addObjectToCache<Type, CacheHost>(obj: Type, cache: CacheHost): CacheHost {
  cache.save(obj);
  return cache;
}

Property 'save' does not exist on type 'CacheHost'.(2339)

What is the difference between declaring one type and then extending to some other type instead of assigning that one type directly?

fierce grove
#

@reef bluff In the second snippet, <Type, CacheHost> creates a generic type called CacheHost that has no relation to your CacheHost type.

reef bluff
#

Alright, that makes more sense now

fierce grove
#

It's the type equivalent of doing:

const x = 0;
function func(x) { /* no relation to outer x */ }
reef bluff
#

It is just a parameter, I understand. So anything after the 'extends' makes reference to any type I have in the scope.

fierce grove
#

Right. Type extends OtherType is like function func(x = y) {} - x is a new variable but y is something that's already in scope.

#

Tangentially, you may want to make your cache itself generic:

type CacheHost<T> = {
  save: (a: T) => void;
}

function addObjectToCache<Type, Cache extends CacheHost<Type>>(obj: Type, cache: Cache): Cache {
reef bluff
#

Thanks a ton for clarifying this 😄