繁体   English   中英

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

[英]TypeScript Conditional type extends object, available only properties

我想实现类型的条件行为。 当我以 object 类型(数组,object,元组,记录)的形式输入泛型时,实际上是任何复合类型,然后我希望该类型表现为该 ZA8CFDE6331BD59EB2AC96F8911C4B666F8911C4B666Z 的 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} extends {[a: string | number]: any}但它也不起作用,甚至上面的代码片段也会在此之后中断。

如果你真的想从类型联合中排除函数,你可以使用Exclude<T, U>实用程序类型来做到这一点:

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

但我不认为这真的能达到你想要的效果:

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

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

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

在元组或 object 明确包含类似函数的值的情况下,这也会将它们删除。 对我来说,这绝对是一种奇怪的行为。


相反,我认为您遇到的问题是,即使您可以在没有它们的情况下对数组类型进行 map,但数组类型的keyof T仍然是所有数组方法和属性的完整列表。 所以我在这里尝试的是制作我自己的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

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

链接到代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM