Skip to content

Commit b621c43

Browse files
committedApr 20, 2020
feat: 🎸 improve type info in ShapeBuilder, improving overall DX
ShapeBuilder has two generics now, one of them represents a ShapeType we are building and another one represents an options based on the type of the shape. This information type checks and suggests completions when using ShapeBuilder.
1 parent 76e35ce commit b621c43

File tree

8 files changed

+83
-42
lines changed

8 files changed

+83
-42
lines changed
 

‎packages/kittik-shape-code/src/Code.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { Shape, ShapeRenderable } from 'kittik-shape-basic';
22
import { Canvas } from 'terminal-canvas';
3+
import { CodeOptions } from './CodeOptions';
34
import { DEFAULT_THEME } from './themes/default';
45
import { js_beautify as beautify } from 'js-beautify';
56
import redeyed from 'redeyed';
67

7-
export class Code extends Shape implements ShapeRenderable {
8+
export { CodeObject } from './CodeObject';
9+
export { CodeOptions } from './CodeOptions';
10+
11+
export class Code extends Shape implements CodeOptions, ShapeRenderable {
812
public get text (): string {
913
return beautify(this.rawText, { indent_size: 2 });
1014
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { CodeOptions } from './CodeOptions';
2+
import { ShapeObject } from 'kittik-shape-basic';
3+
4+
export interface CodeObject extends ShapeObject {
5+
options?: Partial<CodeOptions>
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ShapeOptions } from 'kittik-shape-basic';
2+
3+
export type CodeOptions = ShapeOptions;

‎packages/kittik-shape-rectangle/src/Rectangle.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Shape, ShapeRenderable } from 'kittik-shape-basic';
22
import { Canvas } from 'terminal-canvas';
3+
import { RectangleOptions } from './RectangleOptions';
34

4-
export class Rectangle extends Shape implements ShapeRenderable {
5+
export { RectangleObject } from './RectangleObject';
6+
export { RectangleOptions } from './RectangleOptions';
7+
8+
export class Rectangle extends Shape implements RectangleOptions, ShapeRenderable {
59
public render <T extends Canvas>(canvas: T): void {
610
super.render(canvas);
711

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { RectangleOptions } from './RectangleOptions';
2+
import { ShapeObject } from 'kittik-shape-basic';
3+
4+
export interface RectangleObject extends ShapeObject {
5+
options?: Partial<RectangleOptions>
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ShapeOptions } from 'kittik-shape-basic';
2+
3+
export type RectangleOptions = ShapeOptions;

‎packages/kittik-slide/src/shape/ShapeBuilder.ts

+24-32
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,61 @@
1-
import { SHAPES, ShapeType } from './Shapes';
2-
import { ShapeObject, ShapeOptions, ShapeRenderable } from 'kittik-shape-basic';
1+
import { SHAPES, ShapeOptions, ShapeType } from './Shapes';
2+
import { ShapeObject, ShapeRenderable } from 'kittik-shape-basic';
33

4-
export class ShapeBuilder implements ShapeObject {
5-
public type: ShapeType;
6-
public options?: Partial<ShapeOptions>;
4+
export class ShapeBuilder<T extends ShapeType, O extends ShapeOptions<T>> implements ShapeObject {
5+
public type: T;
6+
public options: Partial<O>;
77

8-
public constructor (type: ShapeType) {
8+
public constructor (type: T) {
99
this.type = type;
10+
this.options = {};
1011
}
1112

12-
public static start (type: ShapeType): ShapeBuilder {
13+
public static start <T extends ShapeType, O extends ShapeOptions<T>>(type: T): ShapeBuilder<T, O> {
1314
return new this(type);
1415
}
1516

16-
public withType (type: ShapeType): this {
17+
public withType (type: T): this {
1718
this.type = type;
18-
1919
return this;
2020
}
2121

22-
public withOptions (options: Partial<ShapeOptions>): this {
22+
public withOptions (options: Partial<O>): this {
2323
this.options = { ...this.options, ...options };
24-
2524
return this;
2625
}
2726

28-
public withText (text: string): this {
29-
this.options = { ...this.options, text };
30-
27+
public withText (text: O['text']): this {
28+
this.options.text = text;
3129
return this;
3230
}
3331

34-
public withX (x: string): this {
35-
this.options = { ...this.options, x };
36-
32+
public withX (x: O['x']): this {
33+
this.options.x = x;
3734
return this;
3835
}
3936

40-
public withY (y: string): this {
41-
this.options = { ...this.options, y };
42-
37+
public withY (y: O['y']): this {
38+
this.options.y = y;
4339
return this;
4440
}
4541

46-
public withWidth (width: string): this {
47-
this.options = { ...this.options, width };
48-
42+
public withWidth (width: O['width']): this {
43+
this.options.width = width;
4944
return this;
5045
}
5146

52-
public withHeight (height: string): this {
53-
this.options = { ...this.options, height };
54-
47+
public withHeight (height: O['height']): this {
48+
this.options.height = height;
5549
return this;
5650
}
5751

58-
public withBackground (background: string): this {
59-
this.options = { ...this.options, background };
60-
52+
public withBackground (background: O['background']): this {
53+
this.options.background = background;
6154
return this;
6255
}
6356

64-
public withForeground (foreground: string): this {
65-
this.options = { ...this.options, foreground };
66-
57+
public withForeground (foreground: O['foreground']): this {
58+
this.options.foreground = foreground;
6759
return this;
6860
}
6961

‎packages/kittik-slide/src/shape/Shapes.ts

+31-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
1-
import { ShapeObject, ShapeRenderable } from 'kittik-shape-basic';
2-
import { Code } from 'kittik-shape-code';
3-
import { FigText } from 'kittik-shape-fig-text';
4-
import { Image } from 'kittik-shape-image';
5-
import { Rectangle } from 'kittik-shape-rectangle';
6-
import { Text } from 'kittik-shape-text';
1+
import { Code, CodeObject, CodeOptions } from 'kittik-shape-code';
2+
import { FigText, FigTextObject, FigTextOptions } from 'kittik-shape-fig-text';
3+
import { Image, ImageObject, ImageOptions } from 'kittik-shape-image';
4+
import { Rectangle, RectangleObject, RectangleOptions } from 'kittik-shape-rectangle';
5+
import { Text, TextObject, TextOptions } from 'kittik-shape-text';
6+
import { Shape } from 'kittik-shape-basic';
77

88
export type ShapeType = 'Code' | 'FigText' | 'Image' | 'Rectangle' | 'Text';
99

10-
// eslint-disable-next-line @typescript-eslint/no-extra-parens
11-
export const SHAPES = new Map<ShapeType, { fromObject: <T extends ShapeObject>(obj: T) => ShapeRenderable }>([
10+
export type ShapeOptions<T extends ShapeType> = T extends 'Code'
11+
? CodeOptions
12+
: T extends 'FigText'
13+
? FigTextOptions
14+
: T extends 'Image'
15+
? ImageOptions
16+
: T extends 'Rectangle'
17+
? RectangleOptions
18+
: T extends 'Text'
19+
? TextOptions
20+
: never;
21+
22+
export type ShapeObject<T extends ShapeType> = T extends 'Code'
23+
? CodeObject
24+
: T extends 'FigText'
25+
? FigTextObject
26+
: T extends 'Image'
27+
? ImageObject
28+
: T extends 'Rectangle'
29+
? RectangleObject
30+
: T extends 'Text'
31+
? TextObject
32+
: never;
33+
34+
export const SHAPES = new Map<ShapeType, typeof Shape>([
1235
['Code', Code],
1336
['FigText', FigText],
1437
['Image', Image],

0 commit comments

Comments
 (0)