当考虑编写泛型函数时,需要记住一条重要规则
调用者选择类型参数
您提供的合同getThing
...
function getThing<T extends Point>(p: T): Partial<T>
...意味着像这样的法律调用,其中T
是一个子类型Point
:
const p: Partial<Point3D> = getThing<Point3D>({x: 1, y: 2, z: 3});
当然,{ x: 10 }
is合法的Partial<Point3D>
.
但是子类型化的能力不仅仅适用于添加附加属性——子类型化还可以包括选择一组更受限制的属性本身的域。你可能有这样的类型:
type UnitPoint = { x: 0 | 1, y: 0 | 1 };
现在当你写的时候
const p: UnitPoint = getThing<UnitPoint>({ x: 0, y: 1});
p.x
有价值10
,即not合法的UnitPoint
.
如果您发现自己处于这种情况,那么您的返回类型很可能实际上并不通用。更准确的函数签名是
function getThing<T extends Point>(p: T): Partial<Point> {