I have the following interface:
export interface WithQueryBuilder {
queryBuilderProps: {
columns: { [key: string]: { enabled: boolean; label: string; key: string } };
meta: Record<string, unknown>;
filters: Record<string, unknown>;
search: {
[key: string]: { enabled?: boolean; key: string; label: string; value: null | string };
};
page: number;
sort: null;
};
}
I now wanna create a new interface that consists of the properties in queryBuilderProps
and some additional ones. I tried the following:
interface TableProps extends Pick<WithQueryBuilder, 'queryBuilderProps'> {
onUpdate?: () => void;
}
What I expected is a type like that:
{
onUpdate: ...,
columns: ...,
filters: ...,
search: ...,
[...]
}
Instead the type looks like this:
{
onUpdate: ...,
withQueryBuilder: { columns, meta, filters, ...),
}
I understand why this happens, but I wonder if there is a way to "pick" all the child definitions instead of the queryBuilderProps
as a whole. Kinda like a spread operator for TypeScript.
Does anything like that exist?
CodePudding user response:
We can use an indexed access type
to look up a specific property on another type:
type Person = { age: number; name: string; alive: boolean }; type Age = Person["age"]; type Age = number
You may still use interface
for your TableProps
as follow:
export interface WithQueryBuilder {
queryBuilderProps: {
columns: { [key: string]: { enabled: boolean; label: string; key: string } };
meta: Record<string, unknown>;
filters: Record<string, unknown>;
search: {
[key: string]: { enabled?: boolean; key: string; label: string; value: null | string };
};
page: number;
sort: null;
};
}
// Here is the important part, this is the correct way to get the sub-type
type QueryBuilderProps = WithQueryBuilder['queryBuilderProps']
// You can still use interface here
interface TableProps extends QueryBuilderProps {
onUpdate?: () => void;
}
const obj: TableProps = {
onUpdate() {},
columns: {
"key": { enabled: true, label: `label`, key: `key` },
},
meta: {},
filters: {},
search: {},
page: 1,
sort: null,
}
// The following will throw error:
// An interface can only extend an identifier/qualified-name with optional type arguments.(2499)
interface TableProps2 extends WithQueryBuilder['queryBuilderProps'] {
onUpdate?: () => void;
}
CodePudding user response:
You can access a sub-property of an Interface
by using square brackets []
:
type TableProps = WithQueryBuilder["queryBuilderProps"] & {
onUpdate?: () => void
}