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 {}
CodePudding user response:
'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.