Want to define interface like this, to create nested paths, is it possible to define interface like this?
interface IPath {
path: string;
name: string;
[key: Exclude<string, 'path' | 'name'>]: IPath
}
this approach not work, there is error: Property 'name' of type 'string' is not assignable to 'string' index type 'IPath'.ts(2411)
CodePudding user response:
You might be able to do it by constructing a massively-complicated string literal key type that allowed strings that weren't "path"
or "name"
, but it would be very complicated (and probably slow to compile) even if it's possible.
Instead, either use a simpler string literal key type via a prefix (or suffix, or some other simple pattern that doesn't match "path"
or "name"
) on children like this, which is fairly similar to what you had, just slightly less open:
type IPath = {
path: string;
name: string;
[key: `child${string}`]: IPath;
};
const example: IPath = {
path: "/something",
name: "something",
childX: {
path: "/something/else",
name: "something-else",
},
childY: {
path: "/some/third/thing",
name: "some third thing",
},
};
...or use a property that's an array of children instead — this is the approach I'd take:
interface IPath {
path: string;
name: string;
children?: IPath[];
}
const example: IPath = {
path: "/something",
name: "something",
children: [
{
path: "/something/else",
name: "something-else",
},
{
path: "/some/third/thing",
name: "some third thing",
},
],
};