2015-11-13 91 views
1

我正在尝试使用updeep库。使用updeep的一个典型的例子是这样的:TypeScript中的超类型约束条件

var person = { 
    name: { 
    first: 'Jane', 
    last: 'West' 
    } 
}; 

var result = u({ name: { first: 'Susan' } }, person); 

这里的想法是,result将是person但随着name.first变化值的克隆。你可以想像这个功能,u,以打字稿定义为:

function u<T>(changes: {}, obj: T): T { ... } 

这捕获的事实,第二个参数的类型也是该函数的返回类型。但它不表示的是changes应该是超级类型T

我想要的是一些类型检查第一个参数。问题是changes争论中存在的值应全部出现在T类型参数中,并与其对应的类型相匹配。表达这允许我们检查changes参数以确保它对于类型TT的超级类型)有意义。

我不确定这是否可以在TypeScript中使用。在像Java这样的语言中,您有关键字super,它可以用来描述类型参数的约束。

虽然打字稿不允许它,这样的表现,我想什么:

function u<T extends U,U extends {}>(changes: U, obj: T): T { ... } 

有谁知道如何表达这样的一个建议吗?拥有用于执行这种转换的类型安全系统将是非常好的。

谢谢。

回答

0

有一个开放的问题,这样的事情,所谓的“局部类型”在这里:https://github.com/Microsoft/TypeScript/issues/4889

Facebook的流量也有类似(但intentionally undocumented)$形状<>类型,它可以在分型可以看出对阵营的setState()

所以基本上,没有,没有这样的功能,可以自动做到这一点。但是,你可以种解决它通过手动这样做:

interface IPartialPerson { 
    name?: { 
    first?: string; 
    last?: string; 
    }; 
    someOptionalProperty?: string; 
} 

interface IPerson extends IPartialPerson { 
    name: { 
    first: string; 
    last: string; 
    }; 
} 

就个人而言,我更喜欢甚至避免后期,只是使用可选的属性尽可能。强制性的财产并不能真正保护你免受任何伤害。即使它们看起来像,它们也不是non-nullable

+0

虽然确实这些是不可空的,但您仍然在这里放弃一定程度的类型安全性。例如,当我在React中创建一个组件时,我指定了一个'props'类型。无论何时我在TSX中实例化该类型,因此都需要任何不是可选的。该要求由编译器执行。让所有东西都可选真的会为各种可能造成混乱的“半成品”实例敞开大门。诚然,它们可以是'null',但是我必须明确地使它们成为'null'**。 –

+0

@MichaelTiller我认为它们有时会很有用,而且我确实倾向于在React道具中使用非可选属性(以及propTypes中的isRequired设置!)。 但是我担心,因为它们会增加更多类型的安全性,所以请避免让我自己(以及任何人阅读代码)假设可选属性受到空值的保护。 – DallonF