• Типизация функции, возвращающей разные объекты?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Проще всего сделать так, ts сам подберёт типы:
    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];
    }

    Но если хочется по правилам, то как-то так:
    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];
    }
    Ответ написан
    1 комментарий
  • Типизация функции, возвращающей разные объекты?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    const elementSettings = {
      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: '',
      }
    } as const;
    
    type Editable<T> = { -readonly [P in keyof T]: T[P]; };
    type ElementSettings = typeof elementSettings;
    
    export function getElementSettings<T extends keyof ElementSettings>(type: T): Editable<ElementSettings[T]> {
      if(type in elementSettings) {
        const settings = {...elementSettings[type]};
        if('options' in settings) {
          (settings as {options: string[]}).options = (settings as {options: string[]}).options.slice();
        }
        return settings;
      }
      throw new Error("element type doesn't match!");
    }
    Ответ написан
    Комментировать