【发布时间】:2018-12-05 20:47:21
【问题描述】:
我正在将我的 react-native 项目从 Flow 迁移到 TypeScript,而我遇到的一个问题是从 Flow 重新创建这种类型:
declare type ApolloData<T, nodeName: string = 'node'> = {
[nodeName]: ?T,
viewer?: ?Viewer,
placeSearch?: ?PlaceConnection,
contactIqLookup?: ?ContactIq,
};
这让我可以输入来自 GraphQL 的数据,如下所示:
const data: ApolloData<Space> = fetchData();
const space: Space = data.node;
// OR
const data: ApolloData<Space, 'space'> = fetchData();
const space: Space = data.space;
我尝试在 TypeScript 中重新创建它,这是我的第一次尝试:
type ApolloData<T, nodeName extends string = 'node'> = {
[node: nodeName]: T | null;
viewer?: Viewer | null;
placeSearch?: PlaceConnection | null;
contactIqLookup?: ContactIq | null;
}
但是,这会产生错误:TS1023: An index signature parameter type must be 'string' or 'number'.
在做了一些研究之后,我了解了Record 类型,这似乎很合适,所以我的第二次尝试更成功了一点:
type ApolloData<T, nodeName extends string = 'node'> =
Record<nodeName, T | null> &
{
viewer?: Viewer | null;
placeSearch?: PlaceConnection | null;
contactIqLookup?: ContactIq | null;
}
但问题在于,其他属性被键入为viewer: Viewer | null | T 而不仅仅是Viewer | null,因为Record 类型适用于该对象的所有属性。
打字稿中是否有任何方法可以接受通用参数化键和值但也有其他字段?
【问题讨论】:
-
你为什么说
viewer: Viewer | null | T?根据我在创建ApolloData实例时的测试结果,一切正常......
标签: typescript flowtype