gpt4 book ai didi

typescript :获取类型的属性字段名称

转载 作者:行者123 更新时间:2023-12-04 14:37:33 25 4
gpt4 key购买 nike

我需要获取 number 类型的所有属性一种类型:

export interface ApplicationQuote {
readonly chronoUnit: ApplicationQuote.ChronoUnitEnum;
readonly downloadedDocs: number;
readonly downloadedKb: number;
readonly uploadedKb: number;
readonly uploadedRefs: number;
}
export namespace ApplicationQuote {
export type ChronoUnitEnum = 'HOUR' | 'DAY' | 'MONTH' | 'YEAR';
export const ChronoUnitEnum = {
HOUR: 'HOUR' as ChronoUnitEnum,
DAY: 'DAY' as ChronoUnitEnum,
MONTH: 'MONTH' as ChronoUnitEnum,
YEAR: 'YEAR' as ChronoUnitEnum
};
}

我需要一个 Array<string>喜欢 ["downloadedDocs", "downloadedKb", "uploadedKb", "uploadedRefs"] .

我试过这个代码:
let names = Object.getOwnPropertyNames(ApplicationQuote);
let keys = Object.keys(ApplicationQuote);

enter image description here

最佳答案

我要重命名您的 ApplicationQuoteIApplicationQuote 的接口(interface), 以区别于 ApplicationQuote命名空间。您会立即发现的一个主要问题是,您无法执行 Object.keys(IApplicationQuote) 之类的操作。 :

Object.keys(IApplicationQuote); // error!
// 'IApplicationQuote' only refers to a type, but is being used as a value here.

接口(interface)是 TypeScript 类型系统的一部分,完全是 erased来自发出的 JavaScript。接口(interface)只在设计时存在,当你编写程序时,可以在编译时检查,当 JavaScript 发出时......但它们在运行时消失了。所以没有任何东西叫 IApplicationQuote在运行时进行处理。

因此,您需要编写如下内容:
const numericProps = [
"downloadedDocs",
"downloadedKb",
"uploadedKb",
"uploadedRefs"
] as const;

( as const 是一个 const assertion ,它允许编译器将 numericProps 视为字符串文字的元组,而不仅仅是 string[] )。

那么,有几种方法可以从这里开始。一种是保留您的界面并使用编译器来帮助确保您的 numericProps value 拥有所有且只有正确的成员。首先我们可以定义 KeysMatching<T, V> ,其计算结果为 T 中的键的并集可分配给类型 V :
type KeysMatching<T, V> = NonNullable<
{ [K in keyof T]: T[K] extends V ? K : never }[keyof T]
>;

并像这样使用它:
type NumericProps = KeysMatching<IApplicationQuote, number>;
// type NumericProps = "downloadedDocs" | "downloadedKb" | "uploadedKb" | "uploadedRefs"

配备 NumericProps类型,我们可以这样写:
type MutuallyAssignable<T extends U, U extends V, V = T> = true;

type NumericPropsOkay = MutuallyAssignable<
typeof numericProps[number],
NumericProps
>; // okay

您可以使用 MutuallyAssignable<T, U>确保您为 T 传入的类型和 U是等价的;如果没有,你会得到一个错误(所以 MutuallyAssignable<string, string | "a"> 很好,但 MutuallyAssignable<number, number | "a"> 不是)。自 NumericPropsOkay不会产生错误,你知道你没有犯错 numericProps .

想想如果你改变会发生什么 numericProps像这样:
const numericProps = [
"downloadedDocs",
"downloadedKb",
"uploadedkb", // <-- note the typo
"uploadedRefs"
] as const;

然后会发生这种情况:
type NumericPropsOkay = MutuallyAssignable<
typeof numericProps[number], // error!
NumericProps
>;
// Type '"uploadedkb"' is not assignable to type
// '"downloadedDocs" | "downloadedKb" | "uploadedKb" | "uploadedRefs"'.

因此,您可以使用它来确保您手动编写的数组和您的接口(interface)定义将来不会发生分歧。

另一种方法是根据 numericProps 定义您的接口(interface)。值(value)。也就是说,按照你的要求做相反的事情...... JavaScript 对 TypeScript 一无所知,但 TypeScript 确实了解 JavaScript。所以你可以采取这个:
const numericProps = [
"downloadedDocs",
"downloadedKb",
"uploadedKb",
"uploadedRefs"
] as const;

并用它来定义这个接口(interface):
export interface IApplicationQuote
extends Readonly<Record<typeof numericProps[number], number>> {
readonly chronoUnit: ApplicationQuote.ChronoUnitEnum;
}

这里我们定义了 IApplicationQuote延长 Readonly<Record<typeof numericProps[number], number>> ,本质上与 {readonly downloadedDocs: number, readonly downloadedKb: number, ...} 相同.我们只需要在那里添加一个非数字属性。你可以确保它有效:
const appQuote: IApplicationQuote = {
chronoUnit: "DAY",
downloadedDocs: 1,
downloadedKb: 2,
uploadedKb: 3,
uploadedRefs: 4
}; // okay

您可以验证 IApplicationQuote仍然是您正在寻找的类型:
const badAppQuote: IApplicationQuote = {
chronoUnit: "DAY",
downloadedDocs: 1,
downloadedKb: 2,
uploadedkb: 3, // error!
uploadedRefs: 4
};
// 'uploadedkb' does not exist in type 'IApplicationQuote'.
// Did you mean to write 'uploadedKb'?

看起来挺好的。

好的,希望有帮助;祝你好运!

Link to code

关于 typescript :获取类型的属性字段名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57592501/

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