How come the type checker is not throwing an error for this indexable type?

I recently delved into the Microsoft Typescript Handbook and found myself intrigued by the indexable types chapter. To gain a deeper understanding, I decided to experiment with the code provided. Strangely enough, upon running this particular piece of code, I was surprised that it did not prompt any errors:

interface NumberDictionary {
  [index: number]: number;
  length: number;
  name: number;
}

// 'x' is not a number, 's' is not a number
let foo: NumberDictionary = { x: 's', length: 2, name: 3 };

Oddly enough, upon removing the initial line in the interface, an error did arise indicating that 'x' was not part of the declared interface.

Answer №1

When you specify an index type, you are essentially stating that the concrete implementation will guarantee the ability to retrieve a number when accessing obj[42].

The type of other properties in the object does not affect this declaration.

With this index specified, it is mandatory for properties like length and name to be numbers, while the others are not strictly enforced. Surprisingly, even though x may seem out of place, it is still permitted with the index declaration. Without the index, TypeScript would enforce the structure of foo as expected and disallow x. However, with the index present, there seems to be no issue raised. Quite strange.

One possible explanation could be that introducing an index interface loosens the type checking to allow both obj["bar"] and obj.bar syntaxes, even if they are ultimately converted to strings internally by TypeScript:

JavaScript converts numerical indexes to strings before using them to access object properties. So, indexing with 100 (a number) is equivalent to indexing with "100" (a string).

(excerpt from the TS handbook referenced in the question)

Therefore, the compiler likely enables index-based calls like foo["anything"], without raising concerns if an undeclared key like anything exists in the value of foo.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In Typescript, issues arise when trying to assign types with inheritance in Generics - Type mismatch detected

As I work on creating a generic parent class to handle multiple children, I have encountered a challenge. My goal is to define an abstract function in the parent class that will take in a child object and return that same class. Here's my initial atte ...

How can I pass a service method as a parameter in an Angular 2 component?

Within the component: myFunction(): void { this.myOtherFunctoin(this._myService.serviceMethod); } private myOtherFunction(func : Function){ func(); } Regarding service calls: serviceMethod(){ this.somethingMethod(); // "this" is coming as ...

Obtaining context from a higher order component in the constructor of a child component: tips and tricks

In order to gain access to context throughout the application, I've implemented the following context provider: import React, { Component, useContext } from 'react'; import { appInitialization, Context } from "@microsoft/teams-js"; ...

Using regular expressions in TypeScript to declare modules

Is there a more efficient method to declare multiple modules in TypeScript? An example of the code I am trying to simplify is: declare module '*.png'; declare module '*.jpg'; declare module '*.gif'; declare module '*.svg ...

Generating output from a callback function in TypeScript

When I execute a graphql query, the showUsers function is supposed to display all users (styled as boxes). However, at the moment, nothing is showing up. I am utilizing a functional component instead of a class component. This function is invoked after m ...

Transforming an object into an interface in TypeScript

Recently, I have started learning Typescript and am currently working on a project where I am building a REST API. In this project, I have defined a specific model for my request payload. However, even after typecasting, the type of 'resObj' rem ...

Tips for resolving TypeScript issues with Vuex mapGetters

When utilizing mapGetters, TypeScript lacks insight into the getters linked to the Vue component, leading to error messages. For instance: import Vue from 'vue'; import { mapActions, mapGetters } from 'vuex'; export default Vue.extend ...

What is the process of extending a class in TypeScript?

I have a few services that contain the same code: constructor (private http: Http) { //use XHR object let _build = (<any> http)._backend._browserXHR.build; (<any> http)._backend._browserXHR.build = () => { let _xhr = _ ...

What is the reason behind the return type of 'MyType | undefined' for Array<MyType>.find(...) method?

Currently, I am in the process of developing an Angular application using TypeScript. As part of this project, I have defined several classes along with corresponding interfaces that align perfectly with their respective properties: Map: export class Map ...

Converting CommonJS default exports into named exports / Unable to load ES module

I've encountered an issue while creating a Discord bot with discord.js using TypeScript. When attempting to run the resulting JavaScript code, I'm facing an error that states: import { Client, FriendlyError, SQLiteProvider } from 'discord.js ...

Creating a build task in Visual Studio Code with universal TypeScript compiler settings

Our project has the following structure: +-- views +-- viewXXX +-- ts ¦ +-- controller.ts ¦ +-- helper.ts ¦ +-- ... (*.ts) +-- viewXXX.ctrl.js // this is the desired output file +-- viewXXX.c ...

Creating an Angular material modal that uses a component wrapper and takes a component as a parameter

Currently, I am in the process of developing a dialog service that will showcase a wrapper component whose parameter is a component to be displayed as the content of the wrapper. open(component: any | TemplateRef<any>, params, viewMode: ViewMode = V ...

Adding a fresh element and removing the initial item from a collection of Objects in JavaScript

I'm working on creating an array of objects that always has a length of five. I want to push five objects initially, and once the array reaches a length of five, I need to pop the first object and push a new object onto the same array. This process sh ...

I am not currently working on developing an angular application

Seeking assistance for the issue described below, as I have been struggling with it for three days. Any help would be greatly appreciated. Despite multiple attempts, the situation only seems to worsen with each try. The problem arises when attempting to ...

The autoimport feature is not supported by the Types Library

My latest project involves a unique library with only one export, an interface named IBasic. After publishing this library on npm and installing it in another project, I encountered an issue. When attempting to import IBasic using the auto-import feature ( ...

Issue with type narrowing and `Extract` helper unexpectedly causing type error in a generic type interaction

I can't seem to figure out the issue at hand. There is a straightforward tagged union in my code: type MyUnion = | { tag: "Foo"; field: string; } | { tag: "Bar"; } | null; Now, there's this generic function tha ...

The variable "$" cannot be found within the current context - encountering TypeScript and jQuery within a module

Whenever I attempt to utilize jQuery within a class or module, I encounter an error: /// <reference path="../jquery.d.ts" /> element: jQuery; // all is good elementou: $; // all is fine class buggers{ private element: jQuery; // The nam ...

Encountering difficulties when trying to deploy Angular 4 with TypeScript on Heroku

I have been facing an issue while trying to deploy my angular 4 app on Heroku. The deployment fails to proceed properly even though everything works fine locally. Here are the relevant files: package.json { "name": "webcli2", "version": "0.0.0", " ...

Angular 8 delivers an observable as a result following a series of asynchronous requests

I am working on a simple function that executes 3 asynchronous functions in sequence: fetchData() { this.fetchUsers('2') .pipe( flatMap((data: any) => { return this.fetchPosts(data.id); }), fl ...

Discovering the JavaScript source file for a package using WebStorm and TypeScript

In my TypeScript project, there is a usage of Express with the following method: response.send('Hello'); I am interested in exploring the implementation of the send() method. However, when I try to navigate to the source code by ctrl+clicking o ...