Skip to content

Commit

Permalink
improve toJSON() return type.
Browse files Browse the repository at this point in the history
  • Loading branch information
endel committed Aug 18, 2023
1 parent cf02f84 commit 01615af
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@colyseus/schema",
"version": "2.0.12",
"version": "2.0.13",
"description": "Binary state serializer with delta encoding for games",
"bin": {
"schema-codegen": "./bin/schema-codegen"
Expand Down
6 changes: 3 additions & 3 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CollectionSchema } from './types/CollectionSchema';
import { SetSchema } from './types/SetSchema';

import { ChangeTree, Ref, ChangeOperation } from "./changes/ChangeTree";
import { NonFunctionPropNames } from './types/HelperTypes';
import { NonFunctionPropNames, ToJSON } from './types/HelperTypes';
import { ClientState } from './filters';
import { getType } from './types/typeRegistry';
import { ReferenceTracker } from './changes/ReferenceTracker';
Expand Down Expand Up @@ -184,7 +184,7 @@ export abstract class Schema {
}

public assign(
props: { [prop in NonFunctionPropNames<this>]?: this[prop] }
props: { [prop in NonFunctionPropNames<this>]?: this[prop] } | ToJSON<this>,
) {
Object.assign(this, props);
return this;
Expand Down Expand Up @@ -898,7 +898,7 @@ export abstract class Schema {
const schema = this._definition.schema;
const deprecated = this._definition.deprecated;

const obj = {}
const obj: ToJSON<typeof this> = {};
for (let field in schema) {
if (!deprecated[field] && this[field] !== null && typeof (this[field]) !== "undefined") {
obj[field] = (typeof (this[field]['toJSON']) === "function")
Expand Down
40 changes: 12 additions & 28 deletions src/types/HelperTypes.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,18 @@
type Bool = 'true' | 'false'
type Key = string | number | symbol;
import { ArraySchema } from "./ArraySchema";
import { MapSchema } from "./MapSchema";

type Not<X extends Bool> = {
true: 'false',
false: 'true'
}[X]

type HaveIntersection<S1 extends string, S2 extends string> = (
{ [K in S1]: 'true' } &
{ [key: string]: 'false' }
)[S2]

type IsNeverWorker<S extends Key> = (
{ [K in S]: 'false' } &
{ [key: string]: 'true' }
)[S]

// Worker needed because of https://github.com/Microsoft/TypeScript/issues/18118
type IsNever<T extends Key> = Not<HaveIntersection<IsNeverWorker<T>, 'false'>>

type IsFunction<T> = IsNever<keyof T>

export type NonFunctionProps<T> = {
[K in keyof T]: {
'false': K,
'true': never
}[IsFunction<T[K]>]
}[keyof T];
export type NonFunctionProps<T> = Omit<T, {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T]>;

export type NonFunctionPropNames<T> = {
[K in keyof T]: T[K] extends Function ? never : K
}[keyof T];

export type ToJSON<T> = Partial<NonFunctionProps<{
[K in keyof T]: T[K] extends MapSchema<infer U>
? Record<string, U>
: T[K] extends ArraySchema<infer U>
? U[]
: T[K]
}>>;
2 changes: 1 addition & 1 deletion test/SchemaTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ describe("Schema Usage", () => {

state.value.set('k1', 1);
const firstEncoded = state.encodeAll();

const decodedState1 = new TestMapSchema();
decodedState1.decode(firstEncoded);
assert.deepStrictEqual(decodedState1.toJSON(), state.toJSON(), `decodedState1.toJSON() EQ state.toJSON()`);
Expand Down

0 comments on commit 01615af

Please sign in to comment.