Реквизиты Vue3 TypeScript с несколькими типами

В качестве упражнения я пытаюсь определить Реализация FontAwesome Vue на TypeScript. Они позволяют опоре icon иметь разные типы:

icon: {
    type: [Object, Array, String],
    required: true
},

Я попытался добавить к нему проверку, но потом props в настройке кажется сломанным:

validator: (prop) => {
    if (typeof prop === 'object') {
        const obj = prop as any;
        return (obj.prefix && obj.iconName);
    } else if (Array.isArray(prop) && prop.length === 2) {
        return true;
    }
    return typeof prop === 'string';
}

Свойство 'icon' не существует для типа 'Readonly ‹{[x: number]: string; } & {длина ?: число | неопределенный; toString ?: строка | неопределенный; toLocaleString ?: строка | неопределенный; concat ?: строка [] | неопределенный; присоединиться ?: строка | неопределенный; срез ?: строка [] | неопределенный; ... еще 16 ...; квартира ?: неизвестно [] | неопределенный; } ›| Только для чтения ‹...› '. Свойство 'icon' не существует для типа 'Readonly ‹{[x: number]: string; } & {длина ?: число | неопределенный; toString ?: строка | неопределенный; toLocaleString ?: строка | неопределенный; concat ?: строка [] | неопределенный; присоединиться ?: строка | неопределенный; срез ?: строка [] | неопределенный; ... еще 16 ...; квартира ?: неизвестно [] | неопределенный; } ›'. Vetur (2339)

Без валидатора я могу сделать это в настройке:

setup(props) {
    let icon: Icon; // simple interface I defined having prefix and iconName
    if (typeof props.icon === 'object') {
        icon = props.icon as Icon;
    } else if (Array.isArray(props.icon) && props.icon.length === 2) {
        icon = {
            prefix: props.icon[0],
            iconName: props.icon[1],
        };
    } else if (typeof props.icon === 'string') {
        icon = {
            prefix: 'l',
            iconName: props.icon as string,
        };
    }
}

Есть идеи, как заставить валидацию работать с этой настройкой? или есть лучший способ определить опору с несколькими типами?


person Thomas    schedule 09.10.2020    source источник


Ответы (1)


Насколько я понимаю, docs выглядит примерно так: нужный:

import { defineComponent, PropType } from 'vue'

interface Icon {
  src: string
  width: number
  height: number
}

const Component = defineComponent({
  props: {
    icon: {
        type: [Object, Array, String] as PropType<Icon | Icon[] | string>,
        required: true
    },
  }
})
person Anbraten    schedule 09.01.2021