Skip to content

Commit 7447dd2

Browse files
authored
feat!: convert date to iso instead of number (#21)
The reason is that Date is an object, not a scalar value, so you can't have it serialized in JSON or Avro. The only way is to transform it to a Unix timestamp (number) or some string standard (like the ISO one). We started with the numeric approach, but we realized that we prefer the ISO one since it's easier for humans to read.
1 parent d3f0d6b commit 7447dd2

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

src/Primitives.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
2+
type Year = `${number}${number}${number}${number}`;
3+
type Month = `${number}${number}`;
4+
type Day = `${number}${number}`;
5+
type Hour = `${number}${number}`;
6+
type Minute = `${number}${number}`;
7+
type Second = `${number}${number}`;
8+
type Milliseconds = `${number}${number}${number}`;
9+
type Timezone = "Z" | `${"+" | "-"}${number}${number}:${number}${number}`;
10+
11+
export type ISODateTime =
12+
`${Year}-${Month}-${Day}T${Hour}:${Minute}:${Second}.${Milliseconds}${Timezone}`;
13+
214
type Methods<T> = {
315
[P in keyof T]: T[P] extends Function ? P : never;
416
}[keyof T];
@@ -9,24 +21,24 @@ type Properties<T> = Omit<MethodsAndProperties<T>, Methods<T>>;
921

1022
type PrimitiveTypes = string | number | boolean | undefined | null;
1123

12-
type DateToNumber<T> = T extends Date ? number : T;
24+
type DateToISODateTime<T> = T extends Date ? ISODateTime : T;
1325

1426
type ValueObjectValue<T> = T extends PrimitiveTypes
1527
? T
1628
: T extends Date
17-
? number
29+
? ISODateTime
1830
: T extends { value: infer U }
19-
? DateToNumber<U>
31+
? DateToISODateTime<U>
2032
: T extends Array<{ value: infer U }>
21-
? DateToNumber<U>[]
33+
? DateToISODateTime<U>[]
2234
: T extends Array<infer U>
2335
? Array<ValueObjectValue<U>>
2436
: T extends { [K in keyof Properties<T>]: unknown }
2537
? {
2638
[K in keyof Properties<T>]: ValueObjectValue<Properties<T>[K]>;
2739
}
2840
: T extends unknown
29-
? DateToNumber<T>
41+
? DateToISODateTime<T>
3042
: never;
3143

3244
export type Primitives<T> = {

tests/Primitives.test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expectTypeOf } from "expect-type";
22

33
import { Primitives } from "../src";
4+
import { ISODateTime } from "../src/Primitives";
45
import { Course } from "./Course";
56
import { DeliveryInfo } from "./DeliveryInfo";
67
import { Learner } from "./Learner";
@@ -70,12 +71,12 @@ describe("Primitives", () => {
7071
expectTypeOf<actualPrimitives>().toEqualTypeOf<expectedPrimitives>();
7172
});
7273

73-
it("should get primitive number type from Date", () => {
74+
it("should get primitive ISO string type from Date", () => {
7475
type actualPrimitives = Primitives<Step>;
7576

7677
type expectedPrimitives = {
7778
readonly name: string;
78-
readonly publishedAt: number;
79+
readonly publishedAt: ISODateTime;
7980
};
8081

8182
expectTypeOf<actualPrimitives>().toEqualTypeOf<expectedPrimitives>();

0 commit comments

Comments
 (0)