JSFiddle - React, Tailwind, and code Playground

by staceyg

TypeScript

interface Renderer<Props extends object = object> {
  id: string;
  render: (props: Props) => void;
}

interface PersonalizedSayHiProps {
  name: string;
}

const sayHiRenderer: Renderer = {
  id: 'sayHi',
  render: () => { console.log('Hi!') }
}
type PersonalizedSayHiRenderer = Renderer<PersonalizedSayHiProps>;

const personalizedSayHiRenderer: PersonalizedSayHiRenderer = {
  id: 'personalizedSayHi',
  render: (props: PersonalizedSayHiProps) => { console.log('Hi ' + props.name + '!') }
}

// Cast to avoid error
const renderers: Renderer[] = [sayHiRenderer as Renderer, personalizedSayHiRenderer as Renderer];

interface Renderable<Props extends object = object> {
  id: string;
  props: Props;
}

const renderables: Renderable[] = [];

function addRenderable(renderable: Renderable) {
  renderables.push(renderable);
}


addRenderable({ id: 'personalizedSayHi', props: { name: 'Stacey'}});
// No type error. :(
addRenderable({ id: 'personalizedSayHi', props: { });

function renderThings() {
  renderables.forEach(renderable => {
    const foundRenderer = renderers.find(rendererToFind => { return rendererToFind.id === renderable.id });
    if (foundRenderer) {
      foundRenderer.render(renderable.props);
    }
  });
}

renderThings();