假設我有一個嵌套物件型別用于定義,比如說,一個用戶:
type TestUser = {
name: string;
email: string;
houses: {
address: string;
rooms: {
floor: number;
color: string;
connectedTo: {
id: number;
}[];
}[];
doors: {
location: number;
size: number;
}[];
}[];
tasks: {
description: string;
people: {
nickname: string;
}[];
}[];
}
我想定義一個可以接受這種型別的泛型函式,然后是該型別嵌套屬性的規范;例如,在這種情況下,這可能看起來像:
const houseSpecification = [{
name: 'houses',
children: [
// (not all subproperties of the type need to be defined, e.g. note how the
// 'tasks' branch is missing altogether)
{
name: 'rooms',
children: [
{
name: 'id',
},
],
},
{
name: 'doors',
},
],
}],
在每個分支中,“name”屬性指定作為物件陣列型別的父屬性的名稱。然后將陣列中物件的型別作為“children”屬性中條目的“name”源。
我正在為任何給定的物件型別采用這種格式的某個函式中尋找這種規范型別的定義,例如作為其引數的in這樣Spec的function myFunction<T extends object>(spec: Spec<T>[])型別。myFunction<TestUser>houseSpecification
我有一些我認為應該作業的東西,但由于某種原因似乎沒有正確遞回:
// extracts the type of an array, e.g. ArrayType<({ id: string })[]> -> { id: string }
export type ArrayType<T> = T extends (infer U)[] ? U : never;
// gives a union type of all keys in an object that yield an array of objects,
// e.g. ObjectArrKeys<{ id: string, data: object[], users: object[] }> -> 'data' | 'users'
export type ObjectArrKeys<T> = {
[K in keyof T]: T[K] extends object[] ? K : never;
}[keyof T];
// used as `function myFunction<T extends object>(spec: Spec<T, ObjectArrKeys<T>>[])`
export type Spec<T extends object, Q extends ObjectArrKeys<T>> = {
name: Q;
children?: Spec<
ArrayType<T[Q]>,
ObjectArrKeys<ArrayType<T[Q]>>
>[]
}
我已經測驗了這兩個實用程式,ArrayType和ObjectArrKeys,它們似乎作業正常。但是,Typescript 似乎不喜歡 in 中的遞回Spec,抱怨ArrayType<T[Q]>與 type 不匹配object,盡管事實上Q只能表示T生成物件陣列的 key 。
有沒有更簡單的方法來獲得我的最終結果?為什么 Typescript 沒有正確推斷這些型別并聲稱它不夠具體?
謝謝。
uj5u.com熱心網友回復:
如果我正確理解了這個問題,這應該可以解決問題:
type Spec<T> = {
[key in ObjectArrKeys<T>]: {
name: key, children?: T[key] extends (infer I)[] ? Spec<I> : never
}
}[ObjectArrKeys<T>][]
首先,既然houseSpecification和嵌套children屬性都是陣列,我也會讓Spec回傳一個陣列型別。我遍歷所有具有陣列屬性的鍵,并構造所有可能的組合的name聯合children。然后,對于每次迭代,我采用推斷的元素型別并遞回呼叫Spec.
在將嵌套物件傳遞給遞回Spec呼叫之前,我再次檢查T[key]確實如此extends (infer I)[]。我認為這些資訊之前丟失了,即使過濾了所有陣列鍵,TypeScript 也并不真正知道它T[key]的型別。any[]ObjectArrKeys
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/470923.html
