Skip to content

Instantly share code, notes, and snippets.

@ratbeard
Created March 11, 2019 16:47
Show Gist options
  • Save ratbeard/1d283015cbed237718ac98698bf6c787 to your computer and use it in GitHub Desktop.
Save ratbeard/1d283015cbed237718ac98698bf6c787 to your computer and use it in GitHub Desktop.
// https://stackoverflow.com/questions/46641380/exhaustive-map-over-a-union-of-typed-objects
// https://www.typescriptlang.org/docs/handbook/advanced-types.html
export function getInteractiveSection2({ question }: {
question: Question;
}) {
switch(question.type) {
case 'multiple-choice':
return <ChoicesSection {...buildItChoice({ question })} />;
case 'fill-in-the-blank':
return <FillInTheBlankView {...buildFillInTheBlankInteraction({ question })} />;
case 'matching':
return <MatchingSection {...buildMatchingInteraction({ question })} />;
// case 'ranking':
// return <RankingInteractionView {...buildRankingInteraction({ question })} />;
default:
return assertUnreachable(question);
}
}
export function getInteractiveSection3({ question }: {
question: Question;
}) {
if (question.type === 'multiple-choice') {
return <ChoicesSection {...buildItChoice({ question })} />;
} else if (question.type === 'fill-in-the-blank') {
return <FillInTheBlankView {...buildFillInTheBlankInteraction({ question })} />;
} else if (question.type === 'matching') {
return <MatchingSection {...buildMatchingInteraction({ question })} />;
} else if (question.type === 'ranking') {
return <RankingInteractionView {...buildRankingInteraction({ question })} />;
} else {
return assertUnreachable(question);
}
}
@ratbeard
Copy link
Author

 2019-03-11 at 11 44 38 AM

@ratbeard
Copy link
Author

export function assertUnreachable(thing: never): never {
  throw new Error(`ERROR assertUnreachable() was called with: ${JSON.stringify(thing)}`);
}

@ratbeard
Copy link
Author

ideally i'd want a switchType(question, { 'multiple-choice': q => , 'fill-in': q => ... })

but have wasted 2 much thyme on that. e.g.:

import { MultipleChoiceQuestion, FillInTheBlankQuestion } from 'shared/backends/lrs';

type BaseTypes = {
  A: { a: string };
  B: { b: number };
}

type DiscriminatedType<M, K extends keyof M> = { type: K } & M[K];
type DiscriminatedTypes<M> = {[K in keyof M]: DiscriminatedType<M, K>};
type DiscriminatedUnion<M, V=DiscriminatedTypes<M>> = V[keyof V];

type Union = DiscriminatedUnion<BaseTypes>

type NarrowedFromUnion<K extends Union['type']> = DiscriminatedType<BaseTypes, K>

const theMap: {[K in Union['type']]: (u: NarrowedFromUnion<K>) => string } = {
  A: ({ a }) => 'this is a: ' + a,
  B: ({ b }) => 'this is b: ' + b
};


export type QuestionTypesMap = {
  'fill-in-the-blank': FillInTheBlankQuestion,
  'multiple-choice': MultipleChoiceQuestion,
};

export type QuestionTypesUnion = DiscriminatedUnion<QuestionTypesMap>;

export type QuestionTypeFn<K extends QuestionTypesUnion['type']> = DiscriminatedType<QuestionTypesMap, K>

export type QuestionTypeHandlers = {[K in QuestionTypesUnion['type']]: (u: QuestionTypeFn<K>) => any }

export const rat: QuestionTypeHandlers = {
  'fill-in-the-blank': (q) => q,
  'multiple-choice': (q) => q,
  // 'y': (q) => q,
}

export type QuestionTypeHandler<K extends QuestionTypesUnion['type'], R> 
  = (q: QuestionTypesMap[K], handlers: QuestionTypeHandlers) => R


// export const switchy = (q: FillInTheBlankQuestion | MultipleChoiceQuestion, handlers: QuestionTypeHandlers) => {
//   const fn = handlers[q.type];
//   if (!fn) {
//     throw new Error(``)
//   } else {
//     return fn(q);
//   }
// }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment