首页 > 解决方案 > 如何将一长串静态属性附加到 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'.

打字稿游乐场


标签: typescript

解决方案


首先,您需要声明静态属性数组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 & StaticProps

如果您创建一个函数并说它是一个TagFnWithStatic没有声明静态属性的类型,Typescript 不会喜欢它,因为必须定义这些属性以满足该类型。为了解决这个问题,让我们分别生成静态属性作为它们自己的对象。

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`

操场


推荐阅读