In TypeScript, it is possible to convert any data type into a numerical map

It appears that typescript permits the casting of any type to a map with keys of type number. Consider this example code:

type NumberMap = {
  [key: number]: string
}

type AnyType = {
  foo: string
  bar: boolean[]
}

const anyTypeObj: AnyType = { foo: "foo", bar: [false] }

const numberMap: NumberMap = anyTypeObj

I initially thought that the last line would result in a type error when trying to assign AnyType to NumberMap, but surprisingly it does not. However, directly assigning an object literal to a variable of type NumberMap does lead to a type error:

const numberMap: NumberMap = { foo: "foo", bar: [false] }

View the link to see the above code on the typescript playground.

What leads typescript to allow the casting of objects of any type to NumberMap? Is there something distinctive about the type { [key: number]: string } that causes this behavior?

Answer №1

Typescript performs additional verification when an object literal is assigned to a variable, known as excess property checking. The purpose is to flag a potential mistake when an object literal is assigned to a variable that does not perfectly match in terms of properties. In JavaScript, inexact assignments are common, so as long as the value's type is compatible with the variable's type, inexact assignments are allowed when the right-hand expression is not an object literal.

In the example provided, anyTypeObj is compatible with NumberMap, where anyTypeObj can be treated as an empty NumberMap. The contract for NumberMap specifies that accessing a property by a numeric key will result in a string, and since anyTypeObj has no numeric keys, this condition holds true.

It's important to note that once anyTypeObj is assigned to numberMap, access to the foo or bar properties via numberMap should not be possible, as those properties are not declared in the NumberMap type.

Edit: margaretkru posed a follow-up question:

Why doesn't { [key: number]: string } enforce that all keys on an object must be of type number and values string? I would expect the cast to NumberMap to fail in that case, as anyTypeObj has properties with string keys.

My explanation is that a variable can accept any value with a type that is compatible with its own type. Compatibility is viewed in terms of subtypes, where a class or interface in object-oriented languages can be considered a subtype if it extends or implements the parent type. Types like AnyType and NumberMap follow this general view of types, with AnyType being a subtype of

NumberMap</code due to its properties adhering to <code>NumberMap
's standards.

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

Substitute terms with the usage of array map

Here is an array for you (2) ['beginning=beginner', 'leaves=leave'] as well as a string its beginner in the sounds leave that has been converted to an array using the following code var words = text.split(' '); My goal ...

Can someone guide me on identifying the type of object in React/Typescript?

Can anyone help me remove this unnecessary definition? const [nextLocation, setNextLocation] = useState(null) as any[]; I have been struggling with this in my React Router 6 project. I've looked through the documentation but haven't found a suit ...

Changing the default route in Angular 2 based on conditions

I'm currently developing an application where, upon entering the page, the default route for the user is the "Login" page. However, I want to implement a condition based on whether the user has a local storage variable (id) set. If this variable exist ...

Node.js is having trouble retrieving information from the SQLite database

Here's a simple code snippet I'm using to retrieve data from my sqlite database. Index.ts: import { Database } from './Class/database'; Database.checkIfExists("some ID"); Database.ts: export class Database { static sqli ...

Creating the upcoming application without @react-google-maps/api is simply not possible

After incorporating a map from the documentation into my component, everything seemed to be functioning correctly in the development version. However, when attempting to build the project, an error arose: Type error: 'GoogleMap' cannot be used as ...

invoking a function within an object in Typescript

export class MockedDataService { constructor(private Session: SessionService) {} private getMockedResponse(name:string){ return ""; // placeholder for the response data, will be a promise } public mocked:{ products:{ ...

Tips on creating a hierarchical ul list from a one-dimensional array of objects

I have an array filled with various objects: const data = [ {id: "0"},{id: "1"},{id: "2"},{id: "00"},{id: "01"},{id: "02"},{id: "11"},{id: "20"},{id: "23"},{id: & ...

In React Router v6, you can now include a custom parameter in createBrowserRouter

Hey there! I'm currently diving into react router v6 and struggling to add custom params in the route object. Unfortunately, I haven't been able to find any examples of how to do it. const AdminRoutes: FunctionComponent = () => { const ...

Clear out chosen elements from Angular Material's mat-selection-list

Looking for a way to delete selected items from an Angular Material list, I attempted to subtract the array of selected items from the initial array (uncertain if this is the correct approach). The challenge I face is figuring out how to pass the array of ...

Encountering unusual results while utilizing interfaces with overloaded arguments

I came across a situation where TypeScript allows calling a method with the wrong type of argument. Why doesn't the TypeScript compiler flag this as an issue? interface IValue { add(value: IValue): IValue; } class NumberValue implements IValue { ...

Conceal the current component when navigating in Angular 2

When I swipe on the app.component, I am being redirected to another component. However, the content of the other component is not fully displayed as it is also showing the content of the app.component. How can I hide the app.component content and only di ...

Is TypeScript capable of comprehending Svelte components?

When it comes to Svelte, the final output is native JavaScript classes, which TypeScript can understand. However, before TypeScript can recognize Svelte components, they must first be compiled from their initial .html form. This can lead to a 'cannot ...

Navigating through different routes in an Angular application can be tricky, especially when dealing

I am facing an issue with the navigation links in my sidebar, which are located within a child module named "login". When I click on "Classroom", it correctly directs me to "login/classroom". However, when I click on "Assignments", it appends "assignment ...

Accessing element from view within controller in Ionic version 3.5

I am currently working on a project in Ionic 3.5, where I need to implement a feature that automatically loads an image "ad" after the page finishes loading. Right now, clicking a button successfully displays the image. However, I want this functionality ...

Error: NullInjector - The injector encountered an error when trying to inject the Component into the MatDialogRef in the AppModule

When utilizing a component via routing as well as injecting it as the "target" of a modal dialog, I encountered an issue: export class Component1 implements OnInit { constructor(private service: <someService>, public dialogRef: MatDialogRef<Compo ...

Angular2- Techniques for exchanging data between isolated components

I am currently working on a project using Angular 2. Within this project, I have created two components: WorkspacesComponent and PagesComponent. In the database, each workspace contains a number of pages. I have written the code below to display the list ...

Exploring the process of dynamically incorporating headers into requests within react-admin

Currently utilizing react-admin with a data provider of simpleRestProvider. I am in need of a solution to dynamically add headers to requests based on user interactions. Is there a way to achieve this? Appreciate any assistance. Thank you! ...

TypeScript's conditional property failing to recognize incorrect functional argument

The concept of a conditional type should encompass smart properties, and I sought assistance from @jcalz in the previous iteration of this query. Even though that issue was resolved, I am still unable to achieve the level of typing strictness I desire. The ...

The extensive magnetic scrolling functionality in Ionic 2 sets it apart from other frameworks

Hi everyone, I could really use some assistance! I've been working on developing an Ionic 2 App and my navigation setup is not too complex. I have a main menu where clicking on an item opens another menu with a submenu. From there, if I click on an i ...

Displaying a component inside a different component

I'm attempting to display components inside another component, but even when I try to include div elements within the component, they don't show up. const DisplayComponent = () => { return ( <div> <DisplayContent ...