TypeScript 将可空类型的元组类型转换为不可空类型的元组

问题描述 投票:0回答:1

我将使用函数来记住给定函数的返回值。

const memoize = (value, onHandle) => {
  for (let index = 0; index < value.length; index++) {
    if (value[index] === null || value[index] === undefined) {
      return
    }
  }
  //
  // Check if there is memoized value with same parameters.
  //
  return onHandle(value)
}

回调函数

onHandle
接收不可为空的值并返回一个被记忆到缓存对象的值。
我应该声明将可空类型的元组转换为不可空类型的元组的类型,如下所示。

type Tuple = [number | undefined, string, boolean, string | undefined]
type StrictTuple = [number, string, boolean, string]

我已经尝试过几次,但推断不可为空的元组实际上非常具有挑战性。有没有什么方法可以绘制仅具有不可空值的元组类型?

这是失败的代码。

type StrictTuple<T extends [unknown, ...unknown[]]> = T extends [
  unknown,
  ...unknown[]
]
  ? T[number] extends null | undefined
    ? never
    : T[number] extends infer U
    ? U extends null | undefined
      ? never
      : T
    : never
  : never;
type Example1 = StrictTuple<[1 | undefined, 2, "3", true | null, boolean]> 
// Example1 shows [1 | undefined, 2, "3", true | null, boolean]
type StrictTuple<T extends [E, ...E[]], E = unknown> = T[number] extends infer U ? U extends null | undefined ? never : [U, ...U[]]: never
type Example2 = StrictTuple<[1, 2, "3", boolean, number | undefined]>
// Example2 shows [number, ...number[]] | [false, ...false[]] | [true, ...true[]] | ["3", ..."3"[]]
typescript tuples type-inference metatype
1个回答
0
投票

您可以编写一个映射类型来执行此操作:

type Strictify<T> = { [K in keyof T]-?: T[K] & {} }

TypeScript 在映射通用元组/数组类型时自动生成元组/数组类型。该定义使用-?

映射修饰符
来表示任何可选属性都应该是必需的。每个属性值类型都与空对象类型 {} 相交
,以从域中删除 
null
undefined
。我也可以使用
NonNullable<>
实用程序类型
(现在)作为这样的交叉点实现

让我们测试一下:

type Example1 = Strictify<[number | undefined, string, boolean, string | undefined]; // ^? type Example1 = [number, string, boolean, string] type Example2 = Strictify<[1, 2, "3", boolean, number | undefined]>; // ^? type Example2 = [1, 2, "3", boolean, number] type Example3 = Strictify<[string | null, number | undefined, boolean?]>; // ^? type Example3 = [string, number, boolean]
看起来不错。请注意,我没有称其为 

StrictTuple

,因为它也适用于非数组对象:

type ExampleObj = Strictify<{ a: string, b?: number, c: boolean | null, d: Date }; /* ^? type ExampleObj = { a: string; b: number; c: boolean; d: Date; } */

Playground 代码链接

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