cbdeveloper
cbdeveloper

Reputation: 31485

Typescript not triggering errors for an uninitialized object property named "name"

I've found some weird behavior on a Typescript code that I'm writing.

Typescript playground link

Somehow Typescript does not trigger an error for an not initialized property if that property name is name :

enter image description here

What is this? Is this a bug or what?

This is the error for the value property:

No value exists in scope for the shorthand property 'value'. Either declare one or provide an initializer.(18004)

enter image description here

interface INTERFACE_A {
    name: string,               // ALSO TRIED WITH OTHER TYPES. SAME RESULT
}

function fooA(x: INTERFACE_A): INTERFACE_A { return x; }

fooA({
    name                        // THIS SHOULD BE AN ERROR (BUT IT'S NOT)
});

const objA: INTERFACE_A = {
    name                        // THIS SHOULD BE AN ERROR (BUT IT'S NOT)
}

interface INTERFACE_B {
    value: string
}

function fooB(x: INTERFACE_B): INTERFACE_B { return x; }

fooB({
    value                       // THIS IS AN ERROR (OK)
});

const objB: INTERFACE_B = {
    value                       // THIS IS AN ERROR (OK)
}

This doesn't seem to be related to the Typescript Playground, since it's also happening in my VSCode dev environment:

enter image description here

enter image description here

UPDATE:

This is probably related to the window.name property, which is of type string. But it still behaves differently than window.innerWidth, for example:

See that TS complains if I use innerWidth as a string, but it does not complain when I try to use window.name as a number:

Typescript playground link

enter image description here

enter image description here

Upvotes: 0

Views: 4637

Answers (2)

Bernie Sumption
Bernie Sumption

Reputation: 504

For a solution to this kind of error, ESLint can be configured to give errors when you use browser globals like name without an explicit reference to the window object (window.name)

  1. Install ESLint
  2. Install ESLint and it for typescript code (instructions here)
  3. install the no-restricted-globals package
  4. Add this to your rules in .eslintrc.js:
module.exports = {
  // ... other fields omitted
  rules: {
    // ... other rules omitted
    "no-restricted-globals": ["error"].concat(
      require("confusing-browser-globals")
    ),
  },
}

Upvotes: 1

Javier García
Javier García

Reputation: 61

{ name } is shorthand for { name: name }, window.name is built-in property, and properties of window are global in browsers, so name is a global property that's equivalent to window.name.

In effect, your code is doing this:

fooA({
  name: window.name
})

and that's totally valid (although probably not what you wanted).

Upvotes: 1

Related Questions