Skip to content

Commit

Permalink
begin adding NoInfer to fix mapping issue
Browse files Browse the repository at this point in the history
  • Loading branch information
ssalbdivad committed Sep 17, 2024
1 parent 4bae3c5 commit 098be52
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 15 deletions.
22 changes: 22 additions & 0 deletions ark/type/__tests__/object.bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,25 @@ bench("dictionary with optional keys", () => {
bench("tuple", () => {
const tuple = type(["string[]", "number[]", ["boolean[]"]])
}).types([3159, "instantiations"])

bench("nested type invocations", () => {
const t = type({
foo: type({
bar: type({
zoo: "string[]"
})
.array()
.or("number"),
superBar: type([
type("string"),
type("number[]"),
type({ inner: type("boolean") })
])
})
.or({
baz: "string",
quux: "1 | 2 | 3"
})
.array()
})
}).types([17173, "instantiations"])
31 changes: 21 additions & 10 deletions ark/type/__tests__/objects/mapped.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,28 @@ contextualize(() => {
attest(t.expression).equals(original.expression)
})

it("change one value", () => {
it("change values", () => {
const original = type({
"foo?": "string",
bar: "number",
baz: "boolean"
baz: {
inner: "string"
}
})
const withNullableBar = original.map(prop => {

const t = original.map(prop => {
if (prop.key === "bar") {
// due to a TS bug, this has to be assigned to a variable,
// otherwise the | null is not inferred: https://github.com/arktypeio/arktype/issues/1132
const nullableBar = prop.value.or("null")
return {
key: prop.key,
value: nullableBar
value: prop.value.or("null")
}
}
if (prop.key === "baz") {
return {
key: prop.key,
value: prop.value.and({
intersectedInner: "number"
})
}
}
return prop
Expand All @@ -37,11 +45,14 @@ contextualize(() => {
const expected = type({
"foo?": "string",
bar: "number | null",
baz: "boolean"
baz: {
inner: "string",
intersectedInner: "number"
}
})

attest<typeof expected>(withNullableBar)
attest(withNullableBar.expression).equals(expected.expression)
attest<typeof expected>(t)
attest(t.expression).equals(expected.expression)
})

it("change optionality", () => {
Expand Down
3 changes: 0 additions & 3 deletions ark/type/__tests__/pipe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,9 +744,6 @@ contextualize(() => {
{}
>`)

const serializedMorphs =
t.internal.firstReferenceOfKindOrThrow("morph").serializedMorphs

attest(t.expression).snap(
"{ l: 1, n: (In: string /^(?!^-0$)-?(?:0|[1-9]\\d*)(?:\\.\\d*[1-9])?$/) => Out<number> } | { n: (In: string /^(?!^-0$)-?(?:0|[1-9]\\d*)(?:\\.\\d*[1-9])?$/) => Out<number>, r: 1 }"
)
Expand Down
4 changes: 2 additions & 2 deletions ark/type/methods/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ interface Type<out t = unknown, $ = {}>
// like "nested 'and' chained from morph on optional"
and<const def, r = type.infer<def, $>>(
def: type.validate<def, $>
): instantiateType<inferIntersection<t, r>, $>
): instantiateType<inferIntersection<t, NoInfer<r>>, $>

or<const def, r = type.infer<def, $>>(
def: type.validate<def, $>
): instantiateType<t | r, $>
): instantiateType<t | NoInfer<r>, $>

array(): ArrayType<t[], $>

Expand Down
2 changes: 2 additions & 0 deletions ark/type/methods/instantiate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import type { ObjectType } from "./object.ts"
import type { StringType } from "./string.ts"
import type { ValidatorType } from "./validator.ts"

// NoInfer avoids return type inference that can lead to incorrect results
// See: https://discord.com/channels/957797212103016458/1285420361415917680/1285545752172429312
export type instantiateType<t, $> =
// if any branch of t is a MorphAst, instantiate it as a MorphType
[Extract<t, InferredMorph>] extends [anyOrNever] ?
Expand Down

0 comments on commit 098be52

Please sign in to comment.