1

I apologize for such a generic question title, but I really don't know how to describe my question in short.

Here is the case:

type Data = {
  id: number
  name: string
}

function func(): Partial<Data> {
  return { name: '' } // ok
}

function wrap<T extends Data>() {
  function func(): Partial<T> {
    return { name: '' } // Type '{ name: ""; }' is not assignable to type 'Partial<T>'
  }
}

The error in second case is a complete mystery for me.

As I know so far, the extends in the function constains T to be a subtype of the specified type. And, as I understand – whatever is subtype of my Data type, it must have id: number and name: string, is it correct? And if it is – then what's wrong with { name: '' } as Partial<T>?

jeron-diovis
  • 788
  • 1
  • 8
  • 19
  • To perhaps simplify your example, the issue persists if you remove the wrapper: `function funcExtends(): Partial { return { name: '' } }` – Etheryte Nov 04 '20 at 19:04

1 Answers1

0

That's because X extends Y in a generic type definition assumes that X should include all properties from Y, but X might have others also. The main point is to supply to a generic entity (class, function...) with a sufficient structure of all inputs. If you try to call your function like this:

wrap<Data & {x: number}>();

There is no error will be. Because Data structure is sufficient. Meantime, you can't return T or Partial<T> because a consumer who will use your function might call it like above, and in such case, it would be incorrect because T would be equaled to Data & {x: number}, the return type would be also the same, but return type from function would be a different type.

  • I'm not sure this answer makes sense, or at least I can't follow it. Given the types in the question, `Partial` should still allow you to return `{ name: string }` since it's a partial of `Data`. – Etheryte Nov 04 '20 at 20:15
  • I understand what you mean, but TS consider ```X``` as it might be a different type. It's just a strict rule. – Николай Гольцев Nov 04 '20 at 20:20