Z
Z
zWaterFall2021-08-01 16:56:52
typescript
zWaterFall, 2021-08-01 16:56:52

Is it possible to specify types dynamically?

There is this code:

enum BLOCK_TYPE {
  PARAGRAPH = 'PARAGRAPH',
  IMAGE = 'IMAGE',
  LIST = 'LIST',
}

interface IBlock {
  type: BLOCK_TYPE;
  body: string | string[];
  file?: File;
}


Is it possible to make it so that
a) When type: "PARAGRAPH" is body : string

b) When type: "IMAGE" is body : File

c) When type: "LIST" is body : string[]

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Stockholm Syndrome, 2021-08-01
@zWaterFall

type ValueOf<T> = T[keyof T];

const enum BlockType {
  Paragpraph = 'PARAGRAPH',
  Image = 'IMAGE',
  List = 'LIST',
}

interface BodyTypes {
  [BlockType.Paragpraph]: string;
  [BlockType.Image]: File;
  [BlockType.List]: string[];
}

interface IBlock<T extends BlockType> {
  type: T; 
  body: BodyTypes[T];
}

type TBlock = ValueOf<{ [P in BlockType]: IBlock<P> }>;
// type TBlock = IBlock<BlockType.Paragpraph> | IBlock<BlockType.Image> | IBlock<BlockType.List>;


function x(b: TBlock) {
  if (b.type === BlockType.Paragpraph) {
    // b.body is string
  } else if (b.type === BlockType.Image) {
    // b.body is File 
  }
}

V
Vasily Bannikov, 2021-08-01
@vabka

const enum BlockType {
  Paragpraph = 'PARAGRAPH',
  Image = 'IMAGE',
  List = 'LIST',
}

type IParagraph = {
  type: BlockType.Paragpraph,
  body: string,
}

type IImage ={
  type: BlockType.Image,
  body: File
}

type IList = {
  type: BlockType.List,
  body: string[]
}

function a(x: string){}
function b(x: string[]){}
function c(x: File){}
type IBlock = IParagraph | IImage | IList;
const blocks: IBlock[] = []
for(const block of blocks){
    switch(block.type) {
        case BlockType.Image:
            c(block.body);
            break;      
        case BlockType.Paragpraph:
            a(block.body);
            break;
        case BlockType.List:
            b(block.body);
            break;
    }
}

Playground
It should also work with interfaces, you just need to narrow the type with extends

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question