Skip to content

Commit 879782b

Browse files
committed
Typing progress
1 parent 06d27e3 commit 879782b

File tree

3 files changed

+54
-34
lines changed

3 files changed

+54
-34
lines changed

src/types.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import type { DagCborEncodable } from "@orbitdb/core";
22

3+
export type RecursivePartial<T> = {
4+
[P in keyof T]?: RecursivePartial<T[P]>;
5+
};
6+
37
export type NestedKey = string | string[];
48
export type PossiblyNestedValueMap = DagCborEncodable | NestedValueMap;
59
export type PossiblyNestedValueObject = DagCborEncodable | NestedValueObject;
@@ -10,9 +14,9 @@ export type NestedValueMap = TypedMap<{[key: string]: PossiblyNestedValueMap}>;
1014
export type NestedValueObject = {
1115
[key: string]: DagCborEncodable | NestedValueObject;
1216
};
13-
export type NestedMapToObject<T extends NestedValueMap> = {
14-
[K in keyof T]: T[K] extends NestedValueMap ? NestedMapToObject<T[K]> : T[K];
15-
};
17+
18+
export type NestedMapToObject<T> = T extends NestedObjectToMap<infer R> ? R : never;
19+
1620
export type NestedObjectToMap<T extends NestedValueObject> = TypedMap<{
1721
[K in keyof T]: T[K] extends NestedValueObject
1822
? NestedObjectToMap<T[K]>

src/utils.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ export const flatten = (
7575
flattened.push({ key: rootKey.join("/"), value: x });
7676
}
7777
};
78-
78+
79+
// @ts-expect-error TODO
7980
recursiveFlatten(xAsMap, []);
8081
return flattened;
8182
};
@@ -110,15 +111,15 @@ export const toNested = (
110111
export const toMap = <T extends NestedValueObject>(
111112
x: T,
112113
): NestedObjectToMap<T> => {
113-
const map: NestedObjectToMap<T> = new Map();
114+
const map = new Map();
114115
for (const [key, value] of Object.entries(x)) {
115116
if (isNestedValueObject(value)) {
116-
map.set(key as Extract<keyof T, string>, toMap(value));
117+
map.set(key, toMap(value));
117118
} else {
118-
map.set(key as Extract<keyof T, string>, value);
119+
map.set(key, value);
119120
}
120121
}
121-
return map;
122+
return map as unknown as NestedObjectToMap<T>;
122123
};
123124

124125
export const toObject = <T extends NestedValueMap>(
@@ -127,9 +128,11 @@ export const toObject = <T extends NestedValueMap>(
127128
const dict = {} as NestedMapToObject<T>;
128129
for (const [key, value] of x.entries()) {
129130
if (value instanceof Map) {
130-
dict[key as keyof T] = toObject(value) as T[keyof T];
131+
// @ts-expect-error TODO
132+
dict[key] = toObject(value);
131133
} else {
132-
dict[key as keyof T] = value as T[keyof T];
134+
// @ts-expect-error TODO
135+
dict[key as keyof T] = value;
133136
}
134137
}
135138
return dict;

test/types.spec.ts

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect } from "aegir/chai";
2-
import { NestedMapToObject, NestedObjectToMap, TypedMap } from "@/types.js";
2+
import { NestedMapToObject, NestedObjectToMap, RecursivePartial, TypedMap } from "@/types.js";
33

44
describe("Types", () => {
55
describe("Typed map", () => {
@@ -30,10 +30,13 @@ describe("Types", () => {
3030

3131
it("two types", () => {
3232
type Structure = { a: number, b: string };
33-
const map = new Map<"a" | "b", number | string>([["a", 1]]) as TypedMap<Structure>;
33+
const map: TypedMap<Structure> = new Map();
3434
let valA: number | undefined = undefined;
3535
valA = map.get("a")
3636
expect(valA).to.equal(1)
37+
38+
// @ts-expect-error Wrong type
39+
valA = map.get("b")
3740
})
3841

3942
it("any key", () => {
@@ -133,49 +136,59 @@ describe("Types", () => {
133136
describe("Nested map to object", () => {
134137
it("simple structure", () => {
135138
type Structure = { a: number, b: string };
136-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = { a: 1, b: "text"}
137-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
139+
const nestedObj: NestedMapToObject<NestedObjectToMap<Structure>> = { a: 1, b: "text" }
140+
nestedObj.a = 3;
138141
})
139142
it("nested structure", () => {
140143
type Structure = { a: number, b: { c: string, d: boolean } };
141-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = { a: 1, b: { c: "text", d: false } };
142-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
144+
const nestedObj: NestedMapToObject<NestedObjectToMap<Structure>> = { a: 1, b: { c: "text", d: false } };
145+
146+
nestedObj.b.c = "test"
143147
})
144148
it("error on wrong key", () => {
145149
type Structure = { a: number, b: string };
146-
// @ts-expect-error
147-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = { c: 1, b: "text" }
148-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
150+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = { }
151+
// @ts-expect-error Wrong key
152+
nestedObj.c = 1
149153
})
150154
it("error on wrong value", () => {
151155
type Structure = { a: number, b: string };
152-
// @ts-expect-error
153-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = { a: "c", b: "text" };
154-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
156+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = { };
157+
// @ts-expect-error Wrong value
158+
nestedObj.a = "c";
155159
})
156160
it("error on wrong nested key", () => {
157161
type Structure = { a: number, b: { c: string, d: boolean } };
158-
// @ts-expect-error
159-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = {}; // todo
160-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
162+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = {};
163+
164+
const bValue = nestedObj["b"];
165+
166+
// @ts-expect-error Wrong key
167+
if (bValue) bValue.e = 3
161168
})
162169
it("error on wrong nested value", () => {
163170
type Structure = { a: number, b: { c: string, d: boolean } };
164-
// @ts-expect-error
165-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = {}; // todo
166-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
171+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = {};
172+
173+
const bValue = nestedObj["b"];
174+
175+
// @ts-expect-error Wrong type
176+
if(bValue) bValue.d = 1
167177
})
168178
it("error on interchanged key values", () => {
169179
type Structure = { a: number, b: string };
170-
// @ts-expect-error
171-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = {}; // todo
172-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
180+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = {};
181+
182+
// @ts-expect-error Interchanged value type
183+
nestedObj.a = "text"
173184
})
174185
it("error on interchanged nested key values", () => {
175186
type Structure = { a: number, b: { c: string, d: boolean } };
176-
// @ts-expect-error
177-
const nestedObj: NestedMapToObject<TypedMap<Structure>> = {}; // todo
178-
expect(nestedObj.keys).to.deep.equal(["a", "b"])
187+
const nestedObj: NestedMapToObject<NestedObjectToMap<RecursivePartial<Structure>>> = {};
188+
189+
const bValue = nestedObj["b"];
190+
// @ts-expect-error Interchanged value type
191+
if (bValue) bValue.c = false;
179192
})
180193
})
181194
})

0 commit comments

Comments
 (0)