简体   繁体   English

在 typescript 接口中有某种“计算”属性吗?

[英]Have some sort of "computed" properties in typescript interfaces?

we are currently blocked by some typescript typings on the ORM part of our project.我们目前在项目的 ORM 部分被一些 typescript 打字阻塞。 We are running our own for some legacy/obscure reasons.出于一些遗留/模糊的原因,我们正在运行我们自己的。

What we'd need now is to be able to correctly type the model's query where conditions to account for relations.我们现在需要的是能够正确键入模型的查询条件以说明关系。 Here's an example:这是一个例子:

interface Model1{
    id:string;
    name:string;
    childId:string;
}
interface Model1Relations{
    child:Model2;
}
type Model1WithRelations = Model1 & Model1Relations;
interface Model2{
    id:string;
    name:string;
}

Pretty straightforward, Model1 uses childId for the belongsTo relation.非常简单,Model1 使用 childId 作为 belongsTo 关系。 We have intermediary interfaces that map the relations parts.我们有 map 关系部分的中介接口。 This allows us to use the basic interface for inserts and updates etc, and the other Model1WithRelations on the selects.这允许我们使用基本接口进行插入和更新等,以及选择上的其他 Model1WithRelations。

When we add a where clause to our query, we define it with an object like so: {name:"Bob"} .当我们向查询添加 where 子句时,我们用 object 定义它,如下所示: {name:"Bob"} The typing is easily done using Partial.使用 Partial 可以轻松完成输入。 (To keep it simple, because we also allow for operators like lowerThan, not equal, includedIn etc). (为简单起见,因为我们还允许使用 lowerThan、not equal、includedIn 等运算符)。

Now, we have (finally) created native joins on our queries and we can now search entities according to their relations.现在,我们(终于)在我们的查询中创建了原生连接,我们现在可以根据它们的关系搜索实体。 If I want to get the model1 that has Bob as its child, I can do {"child.name":"Bob"} , but this does not fulfill the type requirements.如果我想获得以 Bob 作为其子项的 model1,我可以执行{"child.name":"Bob"} ,但这不满足类型要求。

If we use Partial instead, we get to make types work if we change the way we write the where like so: {child:{name:"Bob"}} but we feal it makes things harder to read and understand, considering the conditions can get wild when paired with ANDs, ORs and a couple different operators which are defined by passing an object already like {name:{like:"%bob%"}}如果我们改用 Partial,如果我们改变我们写 where 的方式,我们就可以使类型工作: {child:{name:"Bob"}}但我们认为这会让事情更难阅读和理解,考虑到条件当与 AND、OR 和几个不同的运算符配对时会变得疯狂,这些运算符是通过传递一个 object 已经像{name:{like:"%bob%"}}

Is it do-able?可行吗? Can we achieve what we are looking for?我们可以实现我们正在寻找的东西吗? Which is concatenating a property name with it's type's property names?哪个将属性名称与其类型的属性名称连接起来? I find it hard to believe that this is something possible... So if not, what would you suggest we do, what are others doing about this?我发现很难相信这是可能的……所以如果不是,你会建议我们做什么,其他人在做什么? I see most other ORMs simply do not type their conditions firmly and we feel it causes harm.我看到大多数其他 ORM 只是没有严格地键入它们的条件,我们认为这会造成伤害。

I'm not sure I fully understood your question but here is something you can do:我不确定我是否完全理解您的问题,但您可以执行以下操作:

type ModelRelationsConcatenated<T> = {
    [K in keyof T[keyof T] as `${Exclude<keyof T, symbol>}.${Exclude<K, symbol>}`]: T[keyof T][K];
}

Playground 操场

类型

This is just an example to show it is possible, but you might wanna do some changes to this to better suit your use case.这只是一个例子来说明它是可能的,但您可能想对此进行一些更改以更好地适应您的用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM