为什么我不能返回通用的'T'来满足Partial <t>?

时间:2017-10-27 17:46:03

标签: typescript generics

我在TypeScript中编写了一些代码:

type Point = {
  x: number;
  y: number;
};
function getThing<T extends Point>(p: T): Partial<T> {
  // More interesting code elided
  return { x: 10 };
}

这会产生错误:

  

Type '{ x: 10; }' is not assignable to type 'Partial<T>'

这似乎是一个错误 - { x: 10 }显然是Partial<Point>。什么是TypeScript在这里做错了?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

在考虑编写通用函数时,需要记住一个重要的规则

来电者选择类型参数

您为getThing提供的合同......

function getThing<T extends Point>(p: T): Partial<T>

...意味着像这样的法律调用,其中TPoint的子类型:

const p: Partial<Point3D> = getThing<Point3D>({x: 1, y: 2, z: 3});

当然,{ x: 10 } 是合法的Partial<Point3D>

但是子类型的能力不仅适用于添加其他属性 - 子类型可以包括选择属性的域的更受限制的集合。你可能有这样的类型:

type UnitPoint = { x: 0 | 1, y: 0 | 1 };

现在写的时候

const p: UnitPoint = getThing<UnitPoint>({ x: 0, y: 1});

p.x的值为10是合法的UnitPoint

如果您发现自己处于这种情况,那么您的返回类型实际上不是通用的可能性很大。更精确的函数签名将是

function getThing<T extends Point>(p: T): Partial<Point> {