N
N
Niker2020-10-19 17:28:37
typescript
Niker, 2020-10-19 17:28:37

Typing a function that returns different objects?

Typescript masters, please tell me how to type such a function.

export function getElementSettings(type: keyof typeof elementTypes) {
  switch (type) {
    case 'welcome':
      return {
        placeholder: 'Type welcome message...',
        question: '',
        isDescription: false,
        description: '',
        startButtonText: 'Start',
      };
    case 'checkbox':
      return {
        placeholder: 'Type question or statement...',
        question: '',
        isDescription: false,
        description: '',
        options: [],
        multiple: false,
      };
    case 'dropdown':
      return {
        placeholder: 'Type question here...',
        question: '',
        isDescription: false,
        description: '',
        options: [],
      };
    case 'rating':
      return {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        steps: 10,
        defaultRate: 0,
        shape: 'stars',
      };
    case 'text':
      return {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        maxLength: 99999,
      };
    case 'slider':
      return {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        steps: 10,
      };
    case 'thanks':
      return {
        placeholder: 'Type message...',
        question: '',
        isDescription: false,
        description: '',
      };
    default:
      throw new Error("element type doesn't match!");
  }
}


fields options - an array of strings.

Or maybe there is a better way to organize the creation of such objects?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Aetae, 2020-10-19
@CyberTopTuK

The easiest way to do this is that ts will pick up the types itself:

const elementDefaults = {
  'welcome': {
    placeholder: 'Type welcome message...',
    question: '',
    isDescription: false,
    description: '',
    startButtonText: 'Start',
  },
  'checkbox': {
    placeholder: 'Type question or statement...',
    question: '',
    isDescription: false,
    description: '',
    options: [] as string[],
    multiple: false,
  }, 
  'dropdown': {
    placeholder: 'Type question here...',
    question: '',
    isDescription: false,
    description: '',
    options: [] as string[],
  },
  'rating': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    steps: 10,
    defaultRate: 0,
    shape: 'stars',
  },
  'text': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    maxLength: 99999,
  }, 
  'slider': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    steps: 10,
  }, 
  'thanks': {
    placeholder: 'Type message...',
    question: '',
    isDescription: false,
    description: '',
  }
}


export function getElementSettings<E extends keyof typeof elementTypes>(type: E) {
  if(!(type in elementDefaults)) throw new Error("element type doesn't match!");
  return elementDefaults[type];
}

But if you want according to the rules, then something like this:
type ElementSetting = {
  placeholder: string;
  question: string;
  isDescription: boolean;
  description: string;
}

type ElementSettings = {
  welcome: ElementSetting & {
    startButtonText: string;
  },
  checkbox: ElementSetting & {
    options: string[];
    multiple: boolean;
  },
  dropdown: ElementSetting & {
    options: string[];
  },
  rating: ElementSetting & {
    steps: number;
    defaultRate: number;
    shape: string;
  },
  text: ElementSetting & {
    maxLength: number;
  },
  slider: ElementSetting & {
    steps: number;
  },
  thanks: ElementSetting
}

const elementDefaults: ElementSettings = {
  'welcome': {
    placeholder: 'Type welcome message...',
    question: '',
    isDescription: false,
    description: '',
    startButtonText: 'Start',
  },
  'checkbox': {
    placeholder: 'Type question or statement...',
    question: '',
    isDescription: false,
    description: '',
    options: [],
    multiple: false,
  },
  'dropdown': {
    placeholder: 'Type question here...',
    question: '',
    isDescription: false,
    description: '',
    options: [],
  },
  'rating': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    steps: 10,
    defaultRate: 0,
    shape: 'stars',
  },
  'text': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    maxLength: 99999,
  },
  'slider': {
    placeholder: 'Type question...',
    question: '',
    isDescription: false,
    description: '',
    steps: 10,
  },
  'thanks': {
    placeholder: 'Type message...',
    question: '',
    isDescription: false,
    description: '',
  }
}


export function getElementSettings<E extends keyof ElementSettings>(type: E): ElementSettings[E] {
  if(!(type in elementDefaults)) throw new Error("element type doesn't match!");
  return elementDefaults[type];
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question