如何在流中定义泛型类型,其中所有字段都是可选的指定类型

问题描述 投票:12回答:2

我们可以非常轻松地在typescript中定义一个泛型类型,它可以使所有字段都相对于传递的泛型类型是可选的。这种类型的查询在类型定义中非常有用,用于定义mongo查询的结果,因为我们可能不需要获取所有字段并且可以通过可选类型规范进行验证。

https://www.typescriptlang.org/docs/handbook/advanced-types.html

interface Person {
    name: string;
    age: number;
}

type Partial<T> = {
    [P in keyof T]?: T[P];
}

const p : Partial<Person> = {
    name:"A"
}

如何使用Flow定义相同的东西。我们可以使用$ Keys。但是在定义另一种类型时无法获得其类型,就像我们在类型脚本中所做的那样。 - [T in keyof T]?:T [P];我们无法获得P in Flow。 https://flow.org/en/docs/types/utilities/#toc-keys

type Person = {
    name: string,
    age: number;    
}

type Partial<T> = {
    [$Keys<T>] : 1;  // doubt here how to get type of prop comes in left
}

const p : Partial<Person> = {
    name:"A"
}

实际我们正在尝试为Query编写类型规范。我们也不能为未指定的键赋予null或undefined。

type Department = {
    _id : string,
    name : string,
    type : string
}

type Person = {
    _id : string,
    name : string,
    age : number,
    department : Department
}

type Query <T> = {
    [P in keyOf T ]?: 1 | Query<T[P]> 
}

type Document<T> = {
    [P in keyOf T ]?: T[P] | Document<T[P]>     
}

const personDepartments  : Query<Person> = {
    name:1, department :{name:1}
}

此查询将返回一些结果如下

{_id:"1",name:"abc",department:{name:"xyz"}}

可以是文档类型

const a : Document<Person> = {_id:"1",name:"abc",department:{name:"xyz"}}

所以我们可以编写如下函数

function getResult<T>(query:Query<T>) : Document<t> {
    // code here to query and get result
}

在TypeScript中它非常简单。所以我想在Flow中也应该有解决方法。

typescript flowtype
2个回答
3
投票

你可以使用$Shape实用程序:

复制所提供类型的形状,但将每个字段标记为可选

type Foo = {
  A: string,
  B: number,
  C: string
};

const t: $Shape<Foo> = {
  A: 'a'
};

另一种方法是“传播”类型(抱歉除了changelog之外找不到任何文档):

type Foo = {
  A: string,
  B: number,
  C: string
};

type Partial<T> = { ...T };

const t: Partial<Foo> = {
  A: 'a'
};

现在它真的是部分的,你可以跳过键。


2
投票

您可以使用$ObjMap<T, F>F的每个属性应用函数类型T

type Foo = {
  A: string,
  B: number,
  C: string
};

function makeOptional<T>(t: T): ?T {
  return t;
}

type PartialFoo = $ObjMap<Foo, typeof makeOptional>;

const t: PartialFoo = {
  A: 'a',
  B: null,
  C: undefined
};

但是,在这种情况下,您仍然无法跳过键,但可以将nullundefined添加到其值中。

© www.soinside.com 2019 - 2024. All rights reserved.