Typescript: Error spans are not close enough to missing properties on deeply nested object literals

Created on 24 Feb 2018  路  5Comments  路  Source: microsoft/TypeScript



TypeScript Version: all recent versions, including @next


Search Terms:

missing property literal error

Code

Consider this simplified example:

type Foo = {
    bar: {
        baz: {
            qux: {
                quux: {
                    corge: {
                        grault: {
                            garply: {
                                waldo: {
                                    fred: {
                                        plugh: {
                                            xyzzy: {
                                                thud: {}
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

const foo: Foo = {
    //^^^ error annotated here
    bar: {
        baz: {
            qux: {
                quux: {
                    corge: {
                        grault: {
                            garply: {
                                waldo: {
                                    fred: {
                                        plugh: {
                                            xyzzy: {
                                              // ... for property missing here
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Expected behavior:

The error location should be that of the innermost part of the object literal where the property is missing.

Actual behavior:

The location is reported on the variable being assigned to. The pain of this is exacerbated dramatically if each of the intervening levels of nesting has lots of other properties too. It becomes incredibly laborious to find the real source of the problem.

Playground Link

Context

For context, my real-world use case is typing of Vega JSON specs, which are realized programmatically as large object literals, e.g.

const barChart: Spec = {
  $schema: 'https://vega.github.io/schema/vega/v3.json',
  width: 400,
  height: 200,
  padding: 5,

  data: [
    {
      name: 'table',
      values: [
        { category: 'A', amount: 28 },
        { category: 'B', amount: 55 },
        { category: 'C', amount: 43 },
        { category: 'D', amount: 91 },
        { category: 'E', amount: 81 },
        { category: 'F', amount: 53 },
        { category: 'G', amount: 19 },
        { category: 'H', amount: 87 },
      ],
    },
  ],

  signals: [
    {
      name: 'tooltip',
      value: {},
      on: [
        { events: 'rect:mouseover', update: 'datum' },
        { events: 'rect:mouseout', update: '{}' },
      ],
    },
  ],

  scales: [
    {
      name: 'xscale',
      type: 'band',
      domain: { data: 'table', field: 'category' },
      range: 'width',
      padding: 0.05,
      round: true,
    },
    {
      name: 'yscale',
      domain: { data: 'table', field: 'amount' },
      nice: true,
      range: 'height',
    },
  ],

  axes: [{ orient: 'bottom', scale: 'xscale' }, { orient: 'left', scale: 'yscale' }],

  marks: [
    {
      type: 'rect',
      from: { data: 'table' },
      encode: {
        enter: {
          x: { scale: 'xscale', field: 'category' },
          width: { scale: 'xscale', band: 1 },
          y: { scale: 'yscale', field: 'amount' },
          y2: { scale: 'yscale', value: 0 },
        },
        update: {
          fill: { value: 'steelblue' },
        },
        hover: {
          fill: { value: 'red' },
        },
      },
    },
    {
      type: 'text',
      encode: {
        enter: {
          align: { value: 'center' },
          baseline: { value: 'bottom' },
          fill: { value: '#333' },
        },
        update: {
          x: {
            scale: 'xscale',
            signal: 'tooltip.category',
            band: 0.5,
          },
          y: {
            scale: 'yscale',
            signal: 'tooltip.amount',
            offset: -2,
          },
          text: { signal: 'tooltip.amount' },
          fillOpacity: [{ test: 'datum === tooltip', value: 0 }, { value: 1 }],
        },
      },
    },
  ],
};

(This is a relatively small example as Vega specs go.) If any of the required properties at a deeply nested level is missing, the spec variable is annotated with the error, and one has to hunt through the long error message to discover where the actual problem lies.

Bug Error Messages Moderate Fixed help wanted

Most helpful comment

I think that @weswigham fixed this in TypeScript 3.0 (#25030 bug and #25140 for fix).

All 5 comments

is this issue in community milestone?

It's not clear if we can even fix this without a decent amount of code complexity, since the error can be very non-local, but it's worth a shot. If you'd like to send a PR, we'd appreciate it!

I think that @weswigham fixed this in TypeScript 3.0 (#25030 bug and #25140 for fix).

image

Thanks, this is great to hear!

Was this page helpful?
0 / 5 - 0 ratings