Сейчас нет ругани так:
const props = defineProps({
options: {
// определение массива Record<string,string>, из-за того, что ниже идет el[props.optionLabel]?.toLowerCase(),
// можно как-то сделать так, чтобы это был не Record, а тип объекта с двумя динамическими ключами,
// одно - строка, другое - произвольного типа, по дефолту - {label: string, value: unknown}?
type: Array as PropType<Record<string,string>[]>,
required: true
},
optionLabel: {
type: String,
default: 'label'
},
optionValue: {
type: String,
default: 'value'
}
})
const filter = ref('')
const filteredOptions = computed(() => {
const tmp = filter.value.toLowerCase()
if (tmp === '') return props.options
// вот тут ругается на возможный undefined, если убрать "as string", оно и понятно.
// Можно как-то убрать декларацией типов, чтобы оно также падало, если в props кривота?
// Если просто убрать - то ругается на возможный undefined и требует "?", после чего перестает падать в тестах
return props.options.filter((el) => (el[props.optionLabel] as string).toLowerCase().includes(tmp))
})
есть что-то в документации, что может помочь:
https://vuejs.org/api/sfc-script-setup.html#type-o... но я пока не смог разобраться в TS настолько, чтобы реализовать то, что хочу.
UPD
С помощью генерика получилось сделать так, осталось два костыля:
<script setup lang="ts" generic="T extends {[propName: string]: unknown}">
import { computed, ref } from 'vue'
type keyofString = { [k in keyof T]: T[k] extends string ? k : never }[keyof T]
const {options, optionLabel = 'label' as keyofString, optionValue = 'value' as keyof T} = defineProps<{
options: Partial<T>[], // костыль 1
// когда на вход объединение из нескольких несовместимых типов (разный набор обязательных полей) ошибка по типу такой
// Type 'CategoryEntity[] | GroupEntity[] | SpecializationEntity[]' is not assignable to type 'CategoryEntity[]'.
// Type 'GroupEntity[]' is not assignable to type 'CategoryEntity[]'.
// Type 'GroupEntity' is not assignable to type 'CategoryEntity'.
// Property 'service_groups' is missing in type 'GroupEntity' but required in type '{ id: string; name: string; order: number; // service_groups: GroupEntity[]; }'.ts-plugin(2322)
optionLabel?: keyofString,
optionValue?: keyof T
}>()
///
const filteredOptions = computed(() => {
const tmp = filter.value
if (tmp === '') return options
return options.filter((el) => (el[optionLabel] as string).toLowerCase().includes(tmp)) // костыль 2
// без as string идет ошибка Property 'toLowerCase' does not exist on type 'Partial<T>[keyofString]'.ts-plugin(2339)
// хотя в optionLabel только ключи, у которых в объекте значения типа string (и это работает)
})
буду благодарен, если поможете избавиться от костылей