簡體   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