Skip to content

Commit

Permalink
feat: 🎸 improve type info in ShapeBuilder, improving overall DX
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ghaiklor committed Apr 20, 2020
1 parent 76e35ce commit b621c43
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 42 deletions.
6 changes: 5 additions & 1 deletion packages/kittik-shape-code/src/Code.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Shape, ShapeRenderable } from 'kittik-shape-basic';
import { Canvas } from 'terminal-canvas';
import { CodeOptions } from './CodeOptions';
import { DEFAULT_THEME } from './themes/default';
import { js_beautify as beautify } from 'js-beautify';
import redeyed from 'redeyed';

export class Code extends Shape implements ShapeRenderable {
export { CodeObject } from './CodeObject';
export { CodeOptions } from './CodeOptions';

export class Code extends Shape implements CodeOptions, ShapeRenderable {
public get text (): string {
return beautify(this.rawText, { indent_size: 2 });
}
Expand Down
6 changes: 6 additions & 0 deletions packages/kittik-shape-code/src/CodeObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { CodeOptions } from './CodeOptions';
import { ShapeObject } from 'kittik-shape-basic';

export interface CodeObject extends ShapeObject {
options?: Partial<CodeOptions>
}
3 changes: 3 additions & 0 deletions packages/kittik-shape-code/src/CodeOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ShapeOptions } from 'kittik-shape-basic';

export type CodeOptions = ShapeOptions;
6 changes: 5 additions & 1 deletion packages/kittik-shape-rectangle/src/Rectangle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Shape, ShapeRenderable } from 'kittik-shape-basic';
import { Canvas } from 'terminal-canvas';
import { RectangleOptions } from './RectangleOptions';

export class Rectangle extends Shape implements ShapeRenderable {
export { RectangleObject } from './RectangleObject';
export { RectangleOptions } from './RectangleOptions';

export class Rectangle extends Shape implements RectangleOptions, ShapeRenderable {
public render <T extends Canvas>(canvas: T): void {
super.render(canvas);

Expand Down
6 changes: 6 additions & 0 deletions packages/kittik-shape-rectangle/src/RectangleObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { RectangleOptions } from './RectangleOptions';
import { ShapeObject } from 'kittik-shape-basic';

export interface RectangleObject extends ShapeObject {
options?: Partial<RectangleOptions>
}
3 changes: 3 additions & 0 deletions packages/kittik-shape-rectangle/src/RectangleOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ShapeOptions } from 'kittik-shape-basic';

export type RectangleOptions = ShapeOptions;
56 changes: 24 additions & 32 deletions packages/kittik-slide/src/shape/ShapeBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,61 @@
import { SHAPES, ShapeType } from './Shapes';
import { ShapeObject, ShapeOptions, ShapeRenderable } from 'kittik-shape-basic';
import { SHAPES, ShapeOptions, ShapeType } from './Shapes';
import { ShapeObject, ShapeRenderable } from 'kittik-shape-basic';

export class ShapeBuilder implements ShapeObject {
public type: ShapeType;
public options?: Partial<ShapeOptions>;
export class ShapeBuilder<T extends ShapeType, O extends ShapeOptions<T>> implements ShapeObject {
public type: T;
public options: Partial<O>;

public constructor (type: ShapeType) {
public constructor (type: T) {
this.type = type;
this.options = {};
}

public static start (type: ShapeType): ShapeBuilder {
public static start <T extends ShapeType, O extends ShapeOptions<T>>(type: T): ShapeBuilder<T, O> {
return new this(type);
}

public withType (type: ShapeType): this {
public withType (type: T): this {
this.type = type;

return this;
}

public withOptions (options: Partial<ShapeOptions>): this {
public withOptions (options: Partial<O>): this {
this.options = { ...this.options, ...options };

return this;
}

public withText (text: string): this {
this.options = { ...this.options, text };

public withText (text: O['text']): this {
this.options.text = text;
return this;
}

public withX (x: string): this {
this.options = { ...this.options, x };

public withX (x: O['x']): this {
this.options.x = x;
return this;
}

public withY (y: string): this {
this.options = { ...this.options, y };

public withY (y: O['y']): this {
this.options.y = y;
return this;
}

public withWidth (width: string): this {
this.options = { ...this.options, width };

public withWidth (width: O['width']): this {
this.options.width = width;
return this;
}

public withHeight (height: string): this {
this.options = { ...this.options, height };

public withHeight (height: O['height']): this {
this.options.height = height;
return this;
}

public withBackground (background: string): this {
this.options = { ...this.options, background };

public withBackground (background: O['background']): this {
this.options.background = background;
return this;
}

public withForeground (foreground: string): this {
this.options = { ...this.options, foreground };

public withForeground (foreground: O['foreground']): this {
this.options.foreground = foreground;
return this;
}

Expand Down
39 changes: 31 additions & 8 deletions packages/kittik-slide/src/shape/Shapes.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { ShapeObject, ShapeRenderable } from 'kittik-shape-basic';
import { Code } from 'kittik-shape-code';
import { FigText } from 'kittik-shape-fig-text';
import { Image } from 'kittik-shape-image';
import { Rectangle } from 'kittik-shape-rectangle';
import { Text } from 'kittik-shape-text';
import { Code, CodeObject, CodeOptions } from 'kittik-shape-code';
import { FigText, FigTextObject, FigTextOptions } from 'kittik-shape-fig-text';
import { Image, ImageObject, ImageOptions } from 'kittik-shape-image';
import { Rectangle, RectangleObject, RectangleOptions } from 'kittik-shape-rectangle';
import { Text, TextObject, TextOptions } from 'kittik-shape-text';
import { Shape } from 'kittik-shape-basic';

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

// eslint-disable-next-line @typescript-eslint/no-extra-parens
export const SHAPES = new Map<ShapeType, { fromObject: <T extends ShapeObject>(obj: T) => ShapeRenderable }>([
export type ShapeOptions<T extends ShapeType> = T extends 'Code'
? CodeOptions
: T extends 'FigText'
? FigTextOptions
: T extends 'Image'
? ImageOptions
: T extends 'Rectangle'
? RectangleOptions
: T extends 'Text'
? TextOptions
: never;

export type ShapeObject<T extends ShapeType> = T extends 'Code'
? CodeObject
: T extends 'FigText'
? FigTextObject
: T extends 'Image'
? ImageObject
: T extends 'Rectangle'
? RectangleObject
: T extends 'Text'
? TextObject
: never;

export const SHAPES = new Map<ShapeType, typeof Shape>([
['Code', Code],
['FigText', FigText],
['Image', Image],
Expand Down

0 comments on commit b621c43

Please sign in to comment.