From 7fc6117eded0ee79d959f39be69e863e4adbaf93 Mon Sep 17 00:00:00 2001 From: tjjfvi Date: Sat, 8 Apr 2023 14:59:11 -0400 Subject: [PATCH] separate input and output types --- Readme.md | 4 +- codecs/array.ts | 13 +++--- codecs/compact.ts | 2 +- codecs/deferred.ts | 4 +- codecs/instance.ts | 10 ++--- codecs/int.ts | 2 +- codecs/iterable.ts | 19 ++++---- codecs/lenPrefixed.ts | 2 +- codecs/object.ts | 32 ++++++++++---- codecs/option.ts | 12 +++--- codecs/promise.ts | 2 +- codecs/record.ts | 4 +- codecs/result.ts | 12 +++--- codecs/test/__snapshots__/str.test.ts.snap | 18 +++++++- codecs/transform.ts | 14 +++--- codecs/tuple.ts | 11 +++-- codecs/union.ts | 30 ++++++++----- common/codec.ts | 50 +++++++++------------- common/metadata.ts | 30 ++++++------- examples/collections.eg.ts | 2 +- examples/recursive.eg.ts | 2 +- words.txt | 2 + 22 files changed, 160 insertions(+), 117 deletions(-) diff --git a/Readme.md b/Readme.md index 6859d87..8c92899 100644 --- a/Readme.md +++ b/Readme.md @@ -51,10 +51,10 @@ const decodedValue: Superhero = $superhero.decode(encodedBytes) assertEquals(decodedValue, valueToEncode) ``` -To extract the JS-native TypeScript type from a given codec, use the `Native` utility type. +To extract the type from a given codec, you can use the `Output` utility type. ```ts -type Superhero = $.Native +type Superhero = $.Output // { // pseudonym: string; // secretIdentity?: string | undefined; diff --git a/codecs/array.ts b/codecs/array.ts index 36fd7a3..c531b71 100644 --- a/codecs/array.ts +++ b/codecs/array.ts @@ -12,7 +12,10 @@ type ArrayOfLength< : L extends A["length"] ? A : ArrayOfLength -export function sizedArray($el: Codec, length: L): Codec> { +export function sizedArray($el: Codec, length: L): Codec< + Readonly>, + ArrayOfLength +> { return createCodec({ _metadata: metadata("$.sizedArray", sizedArray, $el, length), _staticSize: $el._staticSize * length, @@ -22,11 +25,11 @@ export function sizedArray($el: Codec, length: L): Codec } }, _decode(buffer) { - const value: T[] = Array(length) + const value: O[] = Array(length) for (let i = 0; i < value.length; i++) { value[i] = $el._decode(buffer) } - return value as ArrayOfLength + return value as ArrayOfLength }, _assert(assert) { assert.instanceof(this, Array) @@ -38,7 +41,7 @@ export function sizedArray($el: Codec, length: L): Codec }) } -export function array($el: Codec): Codec { +export function array($el: Codec): Codec { return createCodec({ _metadata: metadata("$.array", array, $el), _staticSize: compactU32._staticSize, @@ -54,7 +57,7 @@ export function array($el: Codec): Codec { }, _decode(buffer) { const length = compactU32._decode(buffer) - const value: T[] = Array(length) + const value: O[] = Array(length) for (let i = 0; i < value.length; i++) { value[i] = $el._decode(buffer) } diff --git a/codecs/compact.ts b/codecs/compact.ts index e2972c4..3906562 100644 --- a/codecs/compact.ts +++ b/codecs/compact.ts @@ -120,7 +120,7 @@ compactVisitor.add(constant, (codec) => codec) compactVisitor.add(tuple, (codec, ...entries) => { if (entries.length === 0) return codec if (entries.length > 1) throw new Error("Cannot derive compact codec for tuples with more than one field") - return withMetadata(metadata("$.compact", compact, codec), tuple(compact(entries[0]!))) + return withMetadata(metadata("$.compact", compact, codec), tuple(compact(entries[0]!))) }) compactVisitor.add(field, (codec, key, value) => { diff --git a/codecs/deferred.ts b/codecs/deferred.ts index 08d24e0..0434818 100644 --- a/codecs/deferred.ts +++ b/codecs/deferred.ts @@ -1,7 +1,7 @@ import { Codec, createCodec, metadata } from "../common/mod.ts" -export function deferred(getCodec: () => Codec): Codec { - let $codec: Codec +export function deferred(getCodec: () => Codec): Codec { + let $codec: Codec const codec = createCodec({ _metadata: metadata("$.deferred", deferred, getCodec), _staticSize: 0, diff --git a/codecs/instance.ts b/codecs/instance.ts index ef99557..e3b8590 100644 --- a/codecs/instance.ts +++ b/codecs/instance.ts @@ -1,11 +1,11 @@ import { AssertState } from "../common/assert.ts" import { Codec, createCodec, metadata } from "../common/mod.ts" -export function instance( - ctor: new(...args: A) => T, +export function instance( + ctor: new(...args: A) => O, $args: Codec, - toArgs: (value: T) => [...A], -): Codec { + toArgs: (value: I) => [...A], +): Codec { return createCodec({ _metadata: metadata("$.instance", instance, ctor, $args, toArgs), _staticSize: $args._staticSize, @@ -17,7 +17,7 @@ export function instance( }, _assert(assert) { assert.instanceof(this, ctor) - $args._assert(new AssertState(toArgs(assert.value as T), "#arguments", assert)) + $args._assert(new AssertState(toArgs(assert.value as O), "#arguments", assert)) }, }) } diff --git a/codecs/int.ts b/codecs/int.ts index e42c3e4..d46e289 100644 --- a/codecs/int.ts +++ b/codecs/int.ts @@ -96,7 +96,7 @@ export function int(signed: boolean, size: 8 | 16 | 32 | 64 | 128 | 256): Codec< } function intMetadata(signed: boolean, size: number) { - return metadata( + return metadata( metadata(`$.${signed ? "i" : "u"}${size}`), metadata("$.int", int as any, signed, size), ) diff --git a/codecs/iterable.ts b/codecs/iterable.ts index 64ad7e0..07280f6 100644 --- a/codecs/iterable.ts +++ b/codecs/iterable.ts @@ -14,14 +14,14 @@ import { tuple } from "./tuple.ts" const compactU32 = compact(u32) -export function iterable>( +export function iterable, TO = TI, O = I>( props: { - $el: Codec + $el: Codec calcLength: (iterable: I) => number - rehydrate: (iterable: Iterable) => I - assert: (this: Codec, assert: AssertState) => void + rehydrate: (iterable: Iterable) => O + assert: (this: Codec, assert: AssertState) => void }, -): Codec { +): Codec { return createCodec({ _metadata: metadata("$.iterable", iterable, props), _staticSize: compactU32._staticSize, @@ -64,7 +64,7 @@ export function iterable>( }) } -export function set($el: Codec): Codec> { +export function set($el: Codec): Codec, Set> { return withMetadata( metadata("$.set", set, $el), iterable({ @@ -78,8 +78,11 @@ export function set($el: Codec): Codec> { ) } -export function map($key: Codec, $value: Codec): Codec> { - return withMetadata( +export function map( + $key: Codec, + $value: Codec, +): Codec, Map> { + return withMetadata, Map>( metadata("$.map", map, $key, $value), iterable({ $el: tuple($key, $value), diff --git a/codecs/lenPrefixed.ts b/codecs/lenPrefixed.ts index f56ba2b..105c8bb 100644 --- a/codecs/lenPrefixed.ts +++ b/codecs/lenPrefixed.ts @@ -4,7 +4,7 @@ import { u32 } from "./int.ts" const compactU32 = compact(u32) -export function lenPrefixed($inner: Codec): Codec { +export function lenPrefixed($inner: Codec): Codec { return createCodec({ _metadata: metadata("$.lenPrefixed", lenPrefixed, $inner), _staticSize: compactU32._staticSize + $inner._staticSize, diff --git a/codecs/object.ts b/codecs/object.ts index c1460cc..81b2f7d 100644 --- a/codecs/object.ts +++ b/codecs/object.ts @@ -1,8 +1,11 @@ -import { AnyCodec, Codec, CodecVisitor, createCodec, Expand, metadata, Native, U2I } from "../common/mod.ts" +import { AnyCodec, Codec, CodecVisitor, createCodec, Expand, Input, metadata, Output, U2I } from "../common/mod.ts" import { constant } from "./constant.ts" import { option } from "./option.ts" -export function field(key: K, $value: Codec): Codec>> { +export function field(key: K, $value: Codec): Codec< + Expand>>, + Expand> +> { return createCodec({ _metadata: metadata("$.field", field, key, $value), _staticSize: $value._staticSize, @@ -18,7 +21,10 @@ export function field(key: K, $value: Codec): Codec(key: K, $value: Codec): Codec>>> { +export function optionalField(key: K, $value: Codec): Codec< + Expand>>>, + Expand>> +> { const $option = option($value) return createCodec({ _metadata: metadata("$.optionalField", optionalField, key, $value), @@ -43,11 +49,19 @@ export function optionalField(key: K, $value: Codec): }) } -export type NativeObject = Expand< +export type InputObject = Expand< U2I< | { x: {} } | { - [K in keyof T]: { x: Native } + [K in keyof T]: { x: Input } + }[number] + >["x"] +> +export type OutputObject = Expand< + U2I< + | { x: {} } + | { + [K in keyof T]: { x: Output } }[number] >["x"] > @@ -56,17 +70,17 @@ type UnionKeys = T extends T ? keyof T : never export type ObjectMembers = [ ...never extends T ? { [K in keyof T]: - & UnionKeys> + & UnionKeys> & { - [L in keyof T]: K extends L ? never : UnionKeys> + [L in keyof T]: K extends L ? never : UnionKeys> }[number] extends (infer O extends keyof any) - ? [O] extends [never] ? Codec & {}> : Codec<{ [_ in O]?: never }> + ? [O] extends [never] ? Codec & {}> : Codec<{ [_ in O]?: never }> : never } : T, ] -export function object(...members: ObjectMembers): Codec> { +export function object(...members: ObjectMembers): Codec, OutputObject> { return createCodec({ _metadata: metadata("$.object", object, ...members), _staticSize: members.map((x) => x._staticSize).reduce((a, b) => a + b, 0), diff --git a/codecs/option.ts b/codecs/option.ts index f15e798..ac6b4b0 100644 --- a/codecs/option.ts +++ b/codecs/option.ts @@ -1,23 +1,23 @@ import { Codec, createCodec, metadata, ScaleDecodeError } from "../common/mod.ts" -export function option($some: Codec): Codec -export function option($some: Codec, none: U): Codec -export function option($some: Codec, none?: U): Codec { +export function option($some: Codec): Codec +export function option($some: Codec, none: N): Codec +export function option($some: Codec, none?: N): Codec { if ($some._metadata.some((x) => x.factory === option && x.args[1] === none)) { throw new Error("Nested option codec will not roundtrip correctly") } return createCodec({ - _metadata: metadata("$.option", option, $some, ...(none === undefined ? [] : [none!]) as [U]), + _metadata: metadata("$.option", option, $some, ...(none === undefined ? [] : [none!]) as [N]), _staticSize: 1 + $some._staticSize, _encode(buffer, value) { if ((buffer.array[buffer.index++] = +(value !== none))) { - $some._encode(buffer, value as T) + $some._encode(buffer, value as SI) } }, _decode(buffer) { switch (buffer.array[buffer.index++]) { case 0: - return none as U + return none as N case 1: { const value = $some._decode(buffer) if (value === none) { diff --git a/codecs/promise.ts b/codecs/promise.ts index 661c773..24b7a1e 100644 --- a/codecs/promise.ts +++ b/codecs/promise.ts @@ -1,6 +1,6 @@ import { Codec, createCodec, metadata } from "../common/mod.ts" -export function promise($value: Codec): Codec> { +export function promise($value: Codec): Codec, Promise> { return createCodec({ _metadata: metadata("$.promise", promise, $value), _staticSize: $value._staticSize, diff --git a/codecs/record.ts b/codecs/record.ts index cb85aec..44f7fc8 100644 --- a/codecs/record.ts +++ b/codecs/record.ts @@ -4,8 +4,8 @@ import { str } from "./str.ts" import { transform } from "./transform.ts" import { tuple } from "./tuple.ts" -export function record($value: Codec) { - return transform<[string, V][], Record>({ +export function record($value: Codec): Codec>, Record> { + return transform({ $base: array(tuple(str, $value)), encode: Object.entries, decode: Object.fromEntries, diff --git a/codecs/result.ts b/codecs/result.ts index 73c622e..cecf580 100644 --- a/codecs/result.ts +++ b/codecs/result.ts @@ -1,9 +1,9 @@ import { Codec, createCodec, metadata, ScaleDecodeError } from "../common/mod.ts" -export function result( - $ok: Codec, - $err: Codec, -): Codec { +export function result( + $ok: Codec, + $err: Codec, +): Codec { if ($ok._metadata.some((x) => x.factory === result)) { throw new Error("Nested result codec will not roundtrip correctly") } @@ -12,9 +12,9 @@ export function result( _staticSize: 1 + Math.max($ok._staticSize, $err._staticSize), _encode(buffer, value) { if ((buffer.array[buffer.index++] = +(value instanceof Error))) { - $err._encode(buffer, value as Err) + $err._encode(buffer, value as UI) } else { - $ok._encode(buffer, value as Ok) + $ok._encode(buffer, value as TI) } }, _decode(buffer) { diff --git a/codecs/test/__snapshots__/str.test.ts.snap b/codecs/test/__snapshots__/str.test.ts.snap index 9b3966c..a4a3dda 100644 --- a/codecs/test/__snapshots__/str.test.ts.snap +++ b/codecs/test/__snapshots__/str.test.ts.snap @@ -501,7 +501,7 @@ f9 `; snapshot[`\$.str words 1`] = ` -15 +55 03 61 76 @@ -557,6 +557,14 @@ snapshot[`\$.str words 1`] = ` 6f 6e 0a +44 +65 +63 +6f +64 +65 +63 +0a 64 65 6e @@ -578,6 +586,14 @@ snapshot[`\$.str words 1`] = ` 6e 74 0a +45 +6e +63 +6f +64 +65 +63 +0a 68 79 64 diff --git a/codecs/transform.ts b/codecs/transform.ts index 0adadb7..37e9121 100644 --- a/codecs/transform.ts +++ b/codecs/transform.ts @@ -1,13 +1,13 @@ import { AssertState, Codec, createCodec, metadata } from "../common/mod.ts" -export function transform( +export function transform( props: { - $base: Codec - encode: (value: U) => T - decode: (value: T) => U - assert?: (this: Codec, assert: AssertState) => void + $base: Codec + encode: (value: UI) => TI + decode: (value: TO) => UO + assert?: (this: Codec, assert: AssertState) => void }, -): Codec { +): Codec { return createCodec({ _metadata: metadata("$.transform", transform, props), _staticSize: props.$base._staticSize, @@ -19,7 +19,7 @@ export function transform( }, _assert(assert) { props.assert?.call(this, assert) - props.$base._assert(new AssertState(props.encode(assert.value as U), "#encode", assert)) + props.$base._assert(new AssertState(props.encode(assert.value as UI), "#encode", assert)) }, }) } diff --git a/codecs/tuple.ts b/codecs/tuple.ts index 0c21bab..a70c19a 100644 --- a/codecs/tuple.ts +++ b/codecs/tuple.ts @@ -1,10 +1,13 @@ -import { AnyCodec, Codec, createCodec, metadata } from "../common/mod.ts" +import { AnyCodec, Codec, createCodec, Input, metadata, Output } from "../common/mod.ts" -export type NativeTuple = { - [I in keyof ElCodecs]: ElCodecs[I] extends Codec ? T : never +type InputTuple = { + readonly [K in keyof T]: Input +} +type OutputTuple = { + [K in keyof T]: Output } -export function tuple(...codecs: [...T]): Codec> { +export function tuple(...codecs: [...T]): Codec, OutputTuple> { return createCodec({ _metadata: metadata("$.tuple", tuple, ...codecs), _staticSize: codecs.map((x) => x._staticSize).reduce((a, b) => a + b, 0), diff --git a/codecs/union.ts b/codecs/union.ts index 58e0b77..f7e379f 100644 --- a/codecs/union.ts +++ b/codecs/union.ts @@ -1,32 +1,42 @@ -import { AnyCodec, Native } from "../common/codec.ts" +import { AnyCodec, Input, Output } from "../common/codec.ts" import { Codec, createCodec, Expand, metadata, Narrow, ScaleAssertError, ScaleDecodeError } from "../common/mod.ts" import { constant } from "./constant.ts" -import { field, NativeObject, object, ObjectMembers } from "./object.ts" +import { field, InputObject, object, ObjectMembers, OutputObject } from "./object.ts" -export class Variant { - constructor(readonly tag: T, readonly codec: Codec) {} +export class Variant { + constructor(readonly tag: T, readonly codec: Codec) {} } export function variant( tag: T, ...members: ObjectMembers -): Variant> { +): Variant, OutputObject> { return new Variant(tag, object(...members)) } -export type NativeTaggedUnion< +export type InputTaggedUnion< K extends keyof any, - M extends Record>, + M extends Record>, > = { [I in keyof M]: Expand< - Record>["tag"]> & Native>["codec"]> + & Readonly>["tag"]>> + & Input>["codec"]> + > +}[keyof M & number] +export type OutputTaggedUnion< + K extends keyof any, + M extends Record>, +> = { + [I in keyof M]: Expand< + & Record>["tag"]> + & Output>["codec"]> > }[keyof M & number] export function taggedUnion< K extends keyof any, - M extends [] | Record>, ->(tagKey: K, members: M): Codec> { + M extends [] | Record>, +>(tagKey: K, members: M): Codec, OutputTaggedUnion> { const tagToDiscriminant: Record = Object.create(null) const discriminantToMember: Record> = Object.create(null) for (const _discriminant in members) { diff --git a/common/codec.ts b/common/codec.ts index d3cf0ae..e8c2ac4 100644 --- a/common/codec.ts +++ b/common/codec.ts @@ -3,15 +3,16 @@ import { DecodeBuffer, EncodeBuffer } from "./buffer.ts" import { Metadata } from "./metadata.ts" import { ScaleAssertError, ScaleEncodeError } from "./util.ts" -export type Native = T extends Codec ? U : never +export type Input = T extends Codec ? I : never +export type Output = T extends Codec ? O : never -export function createCodec( +export function createCodec( _codec: - & ThisType> - & Pick, "_encode" | "_decode" | "_assert" | "_staticSize" | "_metadata">, -): Codec { + & ThisType> + & Pick, "_encode" | "_decode" | "_assert" | "_staticSize" | "_metadata">, +): Codec { const { _staticSize, _encode, _assert, _decode, _metadata } = _codec - const codec: Codec = { + const codec: Codec = { // @ts-ignore https://gist.github.com/tjjfvi/ea194c4fce76dacdd60a0943256332aa __proto__: Codec.prototype, _staticSize, @@ -24,12 +25,12 @@ export function createCodec( } type NoInfer = T extends infer U ? U : never -export function withMetadata(metadata: Metadata>, codec: Codec): Codec { - const result: Codec = { +export function withMetadata(metadata: Metadata, NoInfer>, codec: Codec): Codec { + const result: Codec = { // @ts-ignore https://gist.github.com/tjjfvi/ea194c4fce76dacdd60a0943256332aa __proto__: Codec.prototype, ...codec, - _metadata: [...metadata as Metadata, ...codec._metadata], + _metadata: [...metadata as Metadata, ...codec._metadata], } return result } @@ -83,33 +84,24 @@ abstract class _Codec { } } -export interface AnyCodec extends _Codec { - _staticSize: number - _encode(buffer: EncodeBuffer, value: any): void - _decode: (buffer: DecodeBuffer) => any - _assert: (state: AssertState) => void - _metadata: any +export type AnyCodec = Codec +export type Encodec = Codec +export type Decodec = Codec - encode(value: any): Uint8Array - encodeAsync(value: any): Promise - decode(array: Uint8Array): any - assert(value: unknown): void -} - -export abstract class Codec extends _Codec implements AnyCodec { +export abstract class Codec extends _Codec implements AnyCodec { /** A static estimation of the size, which may be an under- or over-estimate */ abstract _staticSize: number /** Encodes the value into the supplied buffer, which should have at least `_staticSize` free byte. */ - abstract _encode: (buffer: EncodeBuffer, value: T) => void + abstract _encode: (buffer: EncodeBuffer, value: I) => void /** Decodes the value from the supplied buffer */ - abstract _decode: (buffer: DecodeBuffer) => T + abstract _decode: (buffer: DecodeBuffer) => O /** Asserts that the value is valid for this codec */ abstract _assert: (state: AssertState) => void /** An array with metadata representing the construction of this codec */ - abstract _metadata: Metadata + abstract _metadata: Metadata /** Encodes the value into a new Uint8Array (throws if async) */ - encode(value: T) { + encode(value: I) { const buf = new EncodeBuffer(this._staticSize) this._encode(buf, value) if (buf.asyncCount) throw new ScaleEncodeError(this, value, "Attempted to synchronously encode an async codec") @@ -117,7 +109,7 @@ export abstract class Codec extends _Codec implements AnyCodec { } /** Asynchronously encodes the value into a new Uint8Array */ - async encodeAsync(value: T) { + async encodeAsync(value: I) { const buf = new EncodeBuffer(this._staticSize) this._encode(buf, value) return buf.finishAsync() @@ -130,13 +122,13 @@ export abstract class Codec extends _Codec implements AnyCodec { } /** Requires the codec to have an explicit type annotation; if it doesn't, use `$.assert` instead. */ - assert(value: unknown): asserts value is T { + assert(value: unknown): asserts value is I { assert(this, value) } } /** Asserts that the value is valid for the specified codec */ -export function assert(codec: Codec, value: unknown): asserts value is T { +export function assert(codec: Codec, value: unknown): asserts value is I { codec._assert(new AssertState(value)) } diff --git a/common/metadata.ts b/common/metadata.ts index 3627ae8..f2bfc92 100644 --- a/common/metadata.ts +++ b/common/metadata.ts @@ -1,6 +1,6 @@ import { Codec } from "./codec.ts" -export type Metadata = Array< +export type Metadata = Array< | { type: "atomic" name: string @@ -12,7 +12,7 @@ export type Metadata = Array< type: "factory" name: string docs?: never - factory: (...args: any) => Codec + factory: (...args: any) => Codec args: any[] } | { @@ -24,26 +24,26 @@ export type Metadata = Array< > /** Metadata for an atomic codec */ -export function metadata(name: string): Metadata +export function metadata(name: string): Metadata /** Metadata for a factory-made codec */ -export function metadata( +export function metadata( name: string, - factory: (...args: A) => Codec, + factory: (...args: A) => Codec, ...args: A -): Metadata +): Metadata /** Concatenate multiple metadata arrays */ -export function metadata(...metadata: Metadata[]): Metadata -export function metadata( +export function metadata(...metadata: Metadata[]): Metadata +export function metadata( ...fullArgs: - | Metadata[] + | Metadata[] | [ name: string, - factory?: (...args: any) => Codec, + factory?: (...args: any) => Codec<[I, O]>, ...args: any[], ] -): Metadata { +): Metadata { if (typeof fullArgs[0] !== "string") return fullArgs.flat() - const [name, factory, ...args] = fullArgs as [name: string, factory?: (...args: any) => Codec, ...args: any[]] + const [name, factory, ...args] = fullArgs as [name: string, factory?: (...args: any) => Codec, ...args: any[]] return [ factory ? { @@ -59,17 +59,17 @@ export function metadata( ] } -export function docs(docs: string): Metadata { +export function docs(docs: string): Metadata { return [{ type: "docs", docs }] } export class CodecVisitor { #fallback?: (codec: Codec) => R - #visitors = new Map[number] | Function, (codec: Codec, ...args: any[]) => R>() + #visitors = new Map[number] | Function, (codec: Codec, ...args: any[]) => R>() add(codec: (...args: A) => Codec, fn: (codec: Codec, ...args: A) => R): this add(codec: Codec, fn: (codec: Codec) => R): this - add(codec: Codec | Metadata[number] | Function, fn: (codec: Codec, ...args: any[]) => R): this { + add(codec: Codec | Metadata[number] | Function, fn: (codec: Codec, ...args: any[]) => R): this { if (codec instanceof Codec) { codec = codec._metadata[0]! if (!codec) throw new Error("Cannot register visitor for metadata-less codec") diff --git a/examples/collections.eg.ts b/examples/collections.eg.ts index 38c377b..568d2d0 100644 --- a/examples/collections.eg.ts +++ b/examples/collections.eg.ts @@ -5,4 +5,4 @@ $.set($.u32) // Codec> $.map($.str, $.u32) // Codec> -$.record($.u8) // Codec>> +$.record($.u8) // Codec> diff --git a/examples/recursive.eg.ts b/examples/recursive.eg.ts index f1f5a84..31a08f5 100644 --- a/examples/recursive.eg.ts +++ b/examples/recursive.eg.ts @@ -7,7 +7,7 @@ import { $interestingU8, $pet, InterestingU8 } from "./unions.eg.ts" interface Person { name: string favoriteU8: InterestingU8 - pets: $.Native[] + pets: $.Output[] children: Person[] } diff --git a/words.txt b/words.txt index f88f4f1..e5e1d89 100644 --- a/words.txt +++ b/words.txt @@ -4,9 +4,11 @@ bitvec combinators contravariance cummon +Decodec deno denoland dprint +Encodec hydrokinesis jsbin Kosmoceratops