为啥我不能返回一个通用的 'T' 来满足 Partial<T>?
Posted
技术标签:
【中文标题】为啥我不能返回一个通用的 \'T\' 来满足 Partial<T>?【英文标题】:Why can't I return a generic 'T' to satisfy a Partial<T>?为什么我不能返回一个通用的 'T' 来满足 Partial<T>? 【发布时间】:2022-01-24 03:45:54 【问题描述】:我用 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】:在考虑编写泛型函数时,需要记住一条重要规则
调用者选择类型参数
你为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
是合法的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>
【讨论】:
为什么有人更喜欢通用签名function getThing<T extends Point>(p: T): Partial<Point>;
而不是具体的function getThing(p: Point): Partial<Point>;
?对文字进行过多的属性检查?
你可能会写类似<T>(x: T, y: T)
的东西。单参数版本没有多大意义,但有时很难说服人们他们并不真的需要泛型
我们应该承认以下代码的不一致不会触发错误:function getThing<T extends Point>(p: T): Partial<T> const ret: Partial<T> = ; ret.x = 10; return ret;
。 TS 并不是要始终保持万无一失,所以这样的事情是不可避免的,但可能会令人惊讶。以上是关于为啥我不能返回一个通用的 'T' 来满足 Partial<T>?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能将 const 左值引用绑定到返回 T&& 的函数?
JS中textContent和value有啥区别?同样是取值内容,为啥不能通用?