gpt4 book ai didi

TypeScript 条件类型扩展对象,仅可用属性

转载 作者:行者123 更新时间:2023-12-02 00:13:11 25 4
gpt4 key购买 nike

我想实现类型的条件行为。当我以对象种类(数组、对象、元组、记录)的形式放置泛型时,实际上是任何复合类型,然后我希望该类型表现为该对象的 typeof 字段,但是当给定类型是主要类型时,我想是同一类型。

type B<A> = A extends object ? A[keyof A] : A;
const tuple: [1, 2];
const element:B<typeof tuple> = 2; // # ISSUE - element can be also any method of array

const num: 1;
const numElment:B<typeof num> = 1;

上面的代码有效,但对于复合 B 类型,我还可以从 Array 类型分配所有方法类型。我的问题是 - 我如何指定我只对非功能的事物感兴趣。所以只有纯字段,例如元组,element 应该只是数字。

我也在尝试使用 extends {}extends {[a: string | number]: any} 但它也不起作用,甚至上面的代码片段也会在那之后中断。

最佳答案

如果你真的想从类型联合中排除函数,你可以使用 Exclude<T, U> utility type 来实现:

type ExcludeFunctionProps<T extends object> = Exclude<T[keyof T], Function>;

但我不认为这真的符合您的要求:

type Hmm = ExcludeFunctionProps<["a", "b"]>; // "a" | "b" | 2

在这里Hmm"a" | "b" | 2 .为什么 2 ?因为数组有一个 length数字类型的属性,并且一对元组具有该类型作为数字文字类型 2 .除非您打算包括元组长度,否则这可能不是可行的方法。

type EvenWeirder = ExcludeFunctionProps<[string, () => void]>; // string | 2

如果元组或对象明确包含类似函数的值,这也会将它们删除。对我来说绝对是奇怪的行为。


相反,我认为您遇到了 the issue其中 keyof T对于数组类型仍然是所有数组方法和属性的完整列表,即使您可以 map over array types没有他们。所以我在这里尝试的是制作我自己的 KeyofAfterMapping<T>返回 keyof T对于非数组类型,但只保留 number数组类型的索引键。像这样:

type KeyofAfterMapping<T> = Extract<
keyof T,
T extends any[] ? number : unknown
>;

让我们看看它做了什么:

type KeyofPair = KeyofAfterMapping<["a", "b"]>; // number
type KeyofArray = KeyofAfterMapping<string[]>; // number
type KeyofObject = KeyofAfterMapping<{ a: string; b: number }>; // "a" | "b"

现在我们可以指定 B :

type B<A> = A extends object ? A[KeyofAfterMapping<A>] : A;

并验证它的行为是否符合您的预期:

type TryTupleAgain = B<["a", "b"]>; // "a" | "b"
type KeepsFunctions = B<Array<() => void>>; // () => void
type ObjectsAreStillFine = B<{ a: string; b: number }>; // string | number
type PrimitivesAreStillFine = B<string>; // string

看起来不错。好的,希望有帮助。祝你好运!

Link to code

关于TypeScript 条件类型扩展对象,仅可用属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58182822/

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