【问题标题】:Function returning a variable length generic array tuple返回可变长度通用数组元组的函数
【发布时间】:2021-04-04 16:28:01
【问题描述】:

考虑以下几点:

function makeOutputArrayBasedOnInputArray<T>(arrayOfStuff: T[]) {
    return arrayOfStuff.map(item => ({ item }));
}

const x = makeOutputArrayBasedOnInputArray([1, 'two']);
const y = x[0] // { item: string | number; }
const z = x[1] // { item: string | number; }

我更喜欢的是要显示的类型:

const y = x[0] // { item: number; }
const z = x[1] // { item: string; }

所以想象doIt 函数返回一个完全通用且长度可变的元组类型;由函数的输入驱动。所以这也可以:

const x = makeOutputArrayBasedOnInputArray([7, 'nine', Date]);
const a = x[0] // { item: number; }
const b = x[1] // { item: string; }
const c = x[2] // { item: Date; }

这可能吗?还是我达到了infer 和元组的限制?

另请参阅:Variable length Array tuple in TypeScript? 和 Typescript, generic variadic factory function returning tuple

根据@A_blop 的回答更新:

您好,感谢您的回答!虽然它确实回答了这个问题,但它依赖于使用as const 的调用者。没有as const,唉,它不起作用。

这可能是关键。一些上下文:问题背后的问题是我为改进 react-query 的类型定义而提出的 PR:https://github.com/tannerlinsley/react-query/pull/1527/files

目前的变化是这样的:

export function useQueries<
  TQueryFnData = unknown,
  TError = unknown,
  TData = TQueryFnData
>(
  queries: UseQueryOptions<TQueryFnData, TError, TData>[]
): UseQueryResult<TData, TError>[] {
// ...
}

这很好,但存在非特定类型推断问题。理想情况下,我们会喜欢这种行为:

const result = useQueries([
    { queryKey: key1, queryFn: () => 1 },
    { queryKey: key2, queryFn: () => 'two' },
])
// result[0].data => number | undefined
// result[1].data => string | undefined

但不需要调用者指定as const - 这可能是不可能的吗?

【问题讨论】:

  • 使用变体从被调用方缩小元组的更新答案

标签: typescript tuples inferred-type


【解决方案1】:

您可以添加由映射元组类型组成的显式函数返回类型:

function fn<T extends readonly any[]>(arr: T): {[K in keyof T]: {item: T[K]} } {
    return arr.map(item => ({ item })) as any;
}

const x = fn([1, 'two'] as const);
// x: readonly [{ item: 1; }, { item: "two"; }]
const y = x[0] // y: { item: 1; }
const z = x[1] // z: { item: "two"; }

更新: 要从被调用方缩小类型,您可以使用可变元组类型(TS 4.0):

function fn<T extends readonly any[]>(arr: [...T]): // <-- note [...T]
  {[K in keyof T]: {item: T[K]} } {...}

Playground code

【讨论】:

  • 不错的解决方案。我总是将keyof 用于对象,但你提醒我它对数组也很有用
猜你喜欢
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-10
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
相关资源
最近更新 更多