#typescript
#typescript
Вопрос:
Я пытаюсь ввести эту функцию, к которой добавлен длинный список статических строк в качестве свойств, которые возвращают свойство в виде строкового значения:
const arr = ["a", "b", "c"]; // actual list has about 140 items
const f = (tag: string | undefined) => tag;
arr.forEach(key=> {
f[key] = f(key)
})
console.log(f.a) // "a"
console.log(f.b) // "b"
console.log(f.c) // "c"
console.log(f.d) // undefined
Ошибки:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '(tag: string) => string'. No index signature with a parameter of type 'string' was found on type '(tag: string) => string'.
Property 'a' does not exist on type '(tag: string) => string'.
Property 'b' does not exist on type '(tag: string) => string'.
Property 'c' does not exist on type '(tag: string) => string'.
Property 'd' does not exist on type '(tag: string) => string'.
Ответ №1:
Во-первых, вам нужно объявить массив статических свойств, as const
чтобы создать тип ['a', 'b', 'c']
вместо string[]
.
const arr = ["a", "b", "c"] as const;
Теперь получите эти строковые константы как объединение строковых литералов, получив тип этого массива, а затем индексируя этот тип с помощью number
.
type Keys = (typeof arr)[number] // "a" | "b" | "c"
Затем объявите тип функции и статические свойства отдельно.
type TagFn = (tag: string | undefined) => string | undefined
type StaticProps = { [key in Keys]: string }
Теперь вы можете пересекать эти типы, чтобы сделать статические свойства частью типа функции.
type TagFnWithStatic = TagFn amp; StaticProps
Typescript не понравится, если вы создадите функцию и скажете, что это TagFnWithStatic
тип без объявленных статических свойств, потому что эти свойства должны быть определены, чтобы удовлетворять типу. Чтобы исправить это, давайте создадим статические свойства как их собственный объект отдельно.
const staticProps = arr.reduce((result, prop) => {
result[prop] = prop;
return result
}, {} as StaticProps)
Который затем может быть объединен с функцией при присвоении переменной через Object.assign()
const f: TagFnWithStatic = Object.assign(
(tag: string | undefined) => tag,
staticProps
)
Теперь следующее должно работать так, как вы ожидаете:
f.a // type: string
f.b // type: string
f.c // type: string
f.d // type error, because static property is not present in `arr`