У меня есть следующая упрощенная функция, которая принимает универсальные.
function filter<T>(data: T[]) {
const filter = { field: 'name', type: 'string', condition: 'ct' }
data.forEach((value) => {
type DataPropertyValue = keyof typeof value
// Following does not work
// const dynamicValue = (value[filter.field as DataPropertyValue] as String).toLowerCase() --- This does not work
// const dynamicValue = value[filter.field as DataPropertyValue].toLowerCase() --- This does not work
// But this works but I have to re-instantiate String here
const dynamicValue = String(value[filter.field as DataPropertyValue]).toLowerCase()
console.log(dynamicValue)
})
}
Это работает, но, как вы видите, мне нужно воссоздать экземпляр String
для работы со значением. Есть ли способ сделать это без повторного создания экземпляра String
.
Решение проблемы
Проблема в том, что value
это тип T
, который может быть любым. Это означает, что свойство, которое вы пытаетесь найти, на самом деле может не иметь строкового типа.
Например:
filter([{ name: true }])
Здесь T
было бы типа { name: boolean }
и toLowerCase
вызвано было boolean
бы исключение.
Вы можете исправить это, добавив код, который проверяет, является ли значение правильным типом среды выполнения, прежде чем продолжить.
Это может выглядеть примерно так:
function filter<T>(data: T[]) {
const filter = { field: 'name', type: 'string', condition: 'ct' }
data.forEach((value) => {
const dynamicValue = filter.field in value? value[filter.field as keyof T]: undefined
if (typeof dynamicValue === 'string') {
console.log(dynamicValue.toLowerCase())
} else {
console.log('unsupported property type')
}
})
}
filter([{ name: true }]) // logs "unsupported property type"
filter([{ name: 'FOO' }]) // logs "foo"
Я не уверен, что это именно то, что вам нужно, но я думаю, что это ближе.
Комментариев нет:
Отправить комментарий