Home > OS >  Why is it possible to index an object that has type never?
Why is it possible to index an object that has type never?

Time:12-04

With strict enabled in tsconfig.json, why does tsc not issue an error when indexing an object of type never?

const mystery = ({ foo: 1 } as never)

console.log(mystery['foo'])  // no error
console.log(mystery.foo)  // Property 'foo' does not exist on type 'never'.

export {}

Playground example

CodePudding user response:

It's bug #41021:

'never' (and probably 'void') shouldn't be silently indexable types

DanielRosenwasser commented on Oct 10, 2020

let x = [1, 2, 3, 4].forEach(x => { console.log(x));
x["hello"] = 123;

Expected: an error that x is possibly void or something Actual: no errors


DanielRosenwasser commented on Oct 10, 2020

Actually, never seems to suffer from the same issue..

The TypeScript team are actively fixing it, but no fix is available yet.

Here's a simpler replication:

declare let mystery: never;

console.log(mystery["foo"]);    // No error
console.log(mystery.foo);       // Property 'foo' does not exist on type 'never'.

CodePudding user response:

The never type in TypeScript represents a value that will never occur. In other words, it represents a value that is impossible to obtain. Because of this, it is not possible to access any properties or methods on a value of type never.

However, in the code you provided, the mystery variable is not actually of type never. It is of type { foo: number }. This is because TypeScript type assertions allow you to override the type of a value. In this case, the type assertion as never is telling TypeScript to treat the value of mystery as if it were of type never, even though it is actually of a different type. This is why the first console.log statement does not produce an error.

The second console.log statement does produce an error because it is trying to access a property on a value of type never, which is not allowed.

In short, the reason the code you provided is able to index an object of type never is because the object is not actually of type never, but rather of a different type that has been temporarily "overridden" by a type assertion.

  • Related