Skip to content

Commit 45a1611

Browse files
committed
fix never[] to be []
1 parent a6f9c74 commit 45a1611

File tree

2 files changed

+48
-27
lines changed

2 files changed

+48
-27
lines changed

cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99

1010
async function main () {
1111
const rl = readline.createInterface({ input: stdin })
12-
let ltype: Type = { never: true, count: 1 }
1312

1413
const discriminantPaths: string[] = []
1514
const literalPaths: string[] = []
@@ -30,6 +29,7 @@ async function main () {
3029
// any discriminants are literals too
3130
literalPaths.push(...discriminantPaths)
3231

32+
let ltype: Type = { never: true, count: 1 }
3333
for await (const line of rl) {
3434
if (!line) continue // ignore empty lines
3535
const json = JSON.parse(line)

lib.ts

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,35 @@ function foldleft (xs: Type[]) {
4141
}
4242
}
4343

44-
export function fold (a: Type, b: Type) {
44+
function foldobject (
45+
a: Exclude<Type["object"], undefined>,
46+
b: Exclude<Type["object"], undefined>,
47+
maybe: Record<string, true>,
48+
) {
49+
const object = {}
50+
51+
for (const key in a) {
52+
if (key in b) {
53+
object[key] = fold(a[key], b[key])
54+
} else {
55+
object[key] = a[key]
56+
maybe[key] = true
57+
}
58+
}
59+
60+
for (const key in b) {
61+
if (key in a) {
62+
// do nothing
63+
} else {
64+
object[key] = b[key]
65+
maybe[key] = true
66+
}
67+
}
68+
69+
return { object, maybe }
70+
}
71+
72+
export function fold (a: Type, b: Type): Type {
4573
if (a.never) return { ...b, count: a.count + b.count }
4674
if (b.never) return { ...a, count: a.count + b.count }
4775
if (a.scalar && b.scalar && a.scalar === b.scalar) {
@@ -65,31 +93,20 @@ export function fold (a: Type, b: Type) {
6593
}
6694

6795
if (a.object && b.object) {
68-
if (a.discriminant?.value === b.discriminant?.value) {
69-
const type = {
70-
object: {} as Record<string, Type>,
71-
maybe: { ...a.maybe, ...b.maybe } as Record<string, true>,
96+
if (a.discriminant && b.discriminant && a.discriminant.value === b.discriminant.value) {
97+
return {
98+
...foldobject(a.object, b.object, { ...a.maybe, ...b.maybe }),
7299
discriminant: a.discriminant,
73100
count: a.count + b.count
74-
} satisfies Type
75-
76-
for (const key in a.object) {
77-
if (key in b.object) {
78-
type.object[key] = fold(a.object[key], b.object[key])
79-
} else {
80-
type.object[key] = a.object[key]
81-
type.maybe[key] = true
82-
}
83101
}
84-
for (const key in b.object) {
85-
if (key in a.object) {
86-
// do nothing
87-
} else {
88-
type.object[key] = b.object[key]
89-
type.maybe[key] = true
90-
}
102+
}
103+
104+
if (!a.discriminant && !b.discriminant) {
105+
return {
106+
...foldobject(a.object, b.object, { ...a.maybe, ...b.maybe }),
107+
discriminant: undefined,
108+
count: a.count + b.count
91109
}
92-
return type
93110
}
94111
}
95112

@@ -141,6 +158,7 @@ export function gettype (
141158
for (const key in json) {
142159
const innerPath = `${path}.${key}`
143160
if (omitPaths.includes(innerPath)) continue
161+
144162
keyType = fold(keyType, gettype(key, `${path}|keys`, literalPaths, discriminantPaths, recordPaths, omitPaths))
145163
valueType = fold(valueType, gettype(json[key], `${path}[]`, literalPaths, discriminantPaths, recordPaths, omitPaths))
146164
}
@@ -160,21 +178,23 @@ export function gettype (
160178
if (omitPaths.includes(innerPath)) continue
161179

162180
const ft = gettype(json[key], innerPath, literalPaths, discriminantPaths, recordPaths, omitPaths)
163-
object[key] = ft
164-
if (ft.literal && discriminantPaths.includes(`${path}.${key}`)) {
181+
if (ft.literal && discriminantPaths.includes(innerPath)) {
165182
discriminant = ft.literal
166183
}
184+
185+
object[key] = ft
167186
}
187+
168188
return {
169189
object,
170190
maybe: {},
171-
...(discriminant ? { discriminant } : {}),
191+
discriminant,
172192
count: 1
173193
}
174194
}
175195

176196
if (literalPaths.includes(path)) return { literal: { value: json }, count: 1 }
177-
return { scalar: typeof json, count: 1 } satisfies Type
197+
return { scalar: typeof json, count: 1 }
178198
}
179199

180200
function comment (type: Type, count = false) {
@@ -187,6 +207,7 @@ export function print (type: Type, indent = '', count = false): string {
187207
if (type.literal) return `${JSON.stringify(type.literal.value)}${comment(type, count)}`
188208
if (type.scalar) return `${type.scalar}${comment(type, count)}`
189209
if (type.array) {
210+
if (type.array.never) return `[]${comment(type, count)}`
190211
if (type.array.sum) return `(${print(type.array, indent, count)})[]`
191212
return `${print(type.array, indent, count)}[]`
192213
}

0 commit comments

Comments
 (0)