gpt4 book ai didi

typescript - 如何确保数组的值是 typescript 接口(interface)的键?

转载 作者:搜寻专家 更新时间:2023-10-30 21:19:01 24 4
gpt4 key购买 nike

我正在尝试在 Klass 上生成一个 events 属性,它包含一个字符串数组,该数组与给定接口(interface)的所有键完全匹配。像这样:

interface Events {
one: (foo: string) => void
two: (bar: number) => void
}

class Klass {
protected readonly events: [keyof Events] = ['one', 'two']
}

但是,上面的错误如下:

[ts]
Type '["one", "two"]' is not assignable to type '["one" | "two"]'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'. [2322]
(property) Klass.events: ["one" | "two"]

这里需要什么来确保 events 属性返回一个包含所有事件的数组?

最佳答案

您几乎可以在类型系统(假设 TS3.0+)中用 conditional types 表达这一点, 有一些注意事项:

type Invalid<T> = ["Needs to be all of", T]
const arrayOfAll = <T>() => <U extends T[]>(
...array: U & ([T] extends [U[number]] ? unknown : Invalid<T>[])
) => array;
const arrayOfAllEventKeys = arrayOfAll<keyof Events>();

const goodEvents = arrayOfAllEventKeys('one', 'two'); // okay, type ['one', 'two']

const extraEvents = arrayOfAllEventKeys('one', 'two', 'three'); // error
// ~~~~~~~
// Argument of type "three" is not assignable to parameter of type "one" | "two"

const missingEvents = arrayOfAllEventKeys('one'); // error
// ~~~~~
// Argument of type "one" is not assignable to
// parameter of type ["Needs to be all of", "one" | "two"]

const redundantEvents = arrayOfAllEventKeys('one', 'two', 'one'); // no error
// doesn't enforce distinctness

请注意,goodEvents 被推断为 ['one', 'two'] 类型,并且没有错误。那正是你想要的。您会在额外事件和缺失事件上出错。

警告 1:丢失事件的错误有点神秘; TypeScript 尚不支持 custom error messages ,所以我选择了一些希望可以理解的东西(Argument of type "one"is not assignable to parameter of type ["Needs to be all of", "one"| "two"])。

警告 2:冗余事件没有错误。我找不到通用的方法来要求 arrayOfAllEventKeys 的每个参数都是不同的类型,不会与某些 issues with recursive types 冲突。 .可以使用重载或其他类似技术来处理最长为某个硬编码长度(例如 10)的数组,但我不知道这是否能满足您的需求。让我知道。

希望对您有所帮助;祝你好运!

关于typescript - 如何确保数组的值是 typescript 接口(interface)的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53387838/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com