大家好,我有这样的代码:
import { z } from 'zod'
const options = [
["a", { label: "A" }],
["b", { label: "B" }],
] as const
export function optionsToEnum<T>(entries: ReadonlyArray<Readonly<[value: T, { label: string }]>>): [T, ...T[]] {
const [firstValue, ...restValues] = entries.map(([value]) => value)
return [firstValue, ...restValues]
}
const a = optionsToEnum(options) // typeof a is ["a" | "b", ...("a" | "b")[]] but i expected ["a", "b"]
z.enum(a)
为什么
typeof a
是我期望的["a" | "b", ...("a" | "b")[]]
以及如何解决这个问题?["a", "b"]
问题以及回调签名与映射函数不匹配的问题:
a
:Argument type ([value]: readonly [any]) => any is not assignable to parameter type <T>(value: Readonly<[T, {label: string}]>, index: number, array: Readonly<[T, {label: string}]>[]) => any
问题是类型
import { z } from 'zod';
const options = [
["a", { label: "A" }],
["b", { label: "B" }],
] as const;
type ValueOf<T> = T extends Readonly<[infer U, any]> ? U : never;
export function optionsToEnum<T extends ReadonlyArray<Readonly<[any, { label: string }]>>>(entries: T): { [K in keyof T]: ValueOf<T[K]> } {
return entries.map(([value, _]) => value);
}
const a = optionsToEnum(options);
// typeof a = readonly ["a", "b"]
z.enum(a);
是针对整个数组推断的,而不是针对每个元组元素的单个类型,因此被统一为类型
T
。