diff --git a/ark/repo/scratch.ts b/ark/repo/scratch.ts index 3b2a888ba..64c19f6a2 100644 --- a/ark/repo/scratch.ts +++ b/ark/repo/scratch.ts @@ -10,3 +10,18 @@ const darkColorLiteral = type.enumerated( ) const darkColorRegex = type(`/^(${join(options, "|")})Dark$/`) + +const literalValues = (t: type.Any): t[] => { + const literals: unknown[] = [] + for (const branch of t.internal.branches) { + if (branch.hasKind("unit")) { + literals.push(branch.unit) + } + } + return literals as never +} + +const palette = type.enumerated("red", "blue") + +// ["blue", "red"] +literalValues(palette) diff --git a/ark/type/__tests__/fn.test.ts b/ark/type/__tests__/fn.test.ts index 7b0348644..312225ff6 100644 --- a/ark/type/__tests__/fn.test.ts +++ b/ark/type/__tests__/fn.test.ts @@ -402,6 +402,22 @@ contextualize(() => { }) }) + // https://github.com/arktypeio/arktype/issues/1614 + it("labels an implementation that annotates its optional parameter", () => { + // labels come from the implementation's parameter names, which are only + // cosmetic. contextually inferred parameters already labelled correctly; + // it is annotating the optional one that stopped applyElementLabels from + // matching, dropping every label rather than just that one: + // (args_0?: number | undefined) => number | undefined + const f = type.fn("number?")((n?: number) => n) + + attest(f).type.toString.snap(`TypedFn< + (n?: number | undefined) => number | undefined, + {}, + {} +>`) + }) + describe("scoped", () => { it("scoped param and return", () => { const $ = type.scope({ diff --git a/ark/type/fn.ts b/ark/type/fn.ts index bd39724ee..560909365 100644 --- a/ark/type/fn.ts +++ b/ark/type/fn.ts @@ -38,7 +38,7 @@ export type BaseFnParser<$ = {}> = < externalSignature extends Fn = ( ...args: applyElementLabels< distill.In, - Parameters + Required> > ) => args extends readonly [...unknown[], ":", unknown] ? distill.Out : ReturnType