0

I'm trying to define an optionally-recursive structure in typescript, like this:

interface SceneObject {
  name: string
  type: string
  children?: SceneObject[]
  [k: string]: object|string|Array<number>
}

But ts complains about my children object, saying:Property 'children' of type 'SceneObject[] | undefined' is not assignable to string index type 'string | object | number[]'

It seems to be confused between children and the k catchall at the end. How would I capture this concept of an object that may have a children prop, and if it does, it must be a SceneObject[]?

Note: if I make children non-optional, it compiles OK. Maybe what I need is some way to indicate that the catchall clause must not be "children"?

Edit: here's a worked-out solution:

interface SceneObjectCore {
  name: string
  type: string
  children?: SceneObject[]
}

type SceneObject = SceneObjectCore & {
  [k: string]: object|string|Array<number>
}

let a: SceneObject = {
  name: "myname",
  type: "mytype",
  otherProp: [123],
  children: [{
    name: "name2",
    type: "child"
  }]
}
GaryO
  • 5,873
  • 1
  • 36
  • 61

1 Answers1

0

There's a similar question here: How do I exclude an index signature from a type?

Along with the accepted answer there, I would add that you can define your "catchall" to include undefined which would match your definition for children:

[k: string]: object | string| Array<number>| undefined

jaws
  • 1,952
  • 4
  • 20
  • 27
  • Thanks -- I went with the answer in the question you linked, using an interface and a type that extends it. Added a worked-out example above. – GaryO May 17 '19 at 21:49