Skip to content

Commit

Permalink
feat: 🎸 improve typecheck and autocompletion for SlideBuilder
Browse files Browse the repository at this point in the history
SlideBuilder methods withShape, withAnimation and withOrder has more
type info now. withShape accumulates all the calls with the shapes names
into TShape union type. The same applies to withAnimation, it
accumulates all the calls with the animation names into TAnimation union
type. These union types are used for type check and autocompletion later
in withOrder method.
  • Loading branch information
ghaiklor committed May 3, 2020
1 parent 53d9754 commit 559e1b3
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions packages/kittik-slide/src/slide/SlideBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ import { Canvas } from 'terminal-canvas';
import { ShapeRenderable } from 'kittik-shape-basic';
import { Slide } from './Slide';

export class SlideBuilder {
type TShapeAccumulator<TSlideBuilder, TNextShape> =
TSlideBuilder extends SlideBuilder<infer TShapes, infer TAnimations>
? SlideBuilder<TShapes | TNextShape, TAnimations>
: never;

type TAnimationAccumulator<TSlideBuilder, TNextAnimation> =
TSlideBuilder extends SlideBuilder<infer TShapes, infer TAnimations>
? SlideBuilder<TShapes, TAnimations | TNextAnimation>
: never;

export class SlideBuilder<TShape, TAnimation> {
private readonly slide: Slide = new Slide();

public static start (): SlideBuilder {
public static start (): SlideBuilder<never, never> {
return new this();
}

Expand All @@ -20,18 +30,30 @@ export class SlideBuilder {
return this;
}

public withShape (name: string, shape: ShapeRenderable): this {
public withShape <T extends string>(name: T, shape: ShapeRenderable): TShapeAccumulator<this, T> {
this.slide.addShape(name, shape);

// eslint-disable-next-line no-warning-comments
// TODO: think about returning this and accumulator type here
// Accumulator type in result returns SlideBuilder anyway, so seems like a bug in TypeScript?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this;
}

public withAnimation (name: string, animation: Animationable): this {
public withAnimation <T extends string>(name: T, animation: Animationable): TAnimationAccumulator<this, T> {
this.slide.addAnimation(name, animation);

// eslint-disable-next-line no-warning-comments
// TODO: think about returning this and accumulator type here
// Accumulator type in result returns SlideBuilder anyway, so seems like a bug in TypeScript?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this;
}

public withOrder (shape: string, animations?: string[]): this {
this.slide.addOrder(shape, animations);
public withOrder (shape: TShape, animations?: TAnimation[]): this {
this.slide.addOrder(String(shape), animations?.map(String));
return this;
}

Expand Down

0 comments on commit 559e1b3

Please sign in to comment.