What is the true function of the `as` keyword within a mapped type?

I am new to typescript and I find the usage of as confusing in the following example.

type foo = "a" | "b" | 1 | 2;
type bar = {
    [k in foo as number]: any
}

This example passes type checking. The resulting bar type is transformed into

type bar = {
    [x: number]: any
}

How does k in foo as number get translated into x: number?

Answer №1

Within your code, you are utilizing key remapping in mapped types, a concept distinct from a type assertion. Despite both employing the as keyword, they serve different purposes. It's merely coincidental that they share this keyword.

A standard non-remapped mapped type format is {[T in KK]: V<T>}, where it defines a type parameter T iterating over the union members of key-like type KK (required to be a subtype of PropertyKey). Each union member T results in a property with key T and value V<T>. The output value can be any function of type parameter T, while the key type is confined to just T.

In contrast, key remapping allows the type parameter to iterate over any union, computing both keys and values. The format is

{[T in U as K<T>]: V<T>}
, where it iterates over union members of type U, assigning properties with keys based on K<T> and values as V<T>.

In your provided example:

type Foo = "a" | "b" | 1 | 2;
type Bar = {
  [K in Foo as number]: any
}

This is considered a degenerate case, neglecting Foo when determining the key type. Instead, the key type is fixed as number. Thus, the output features a single number index signature with a value type of any.

To illustrate a more realistic use case, consider defining the key as a template literal type dependent on K:

type Baz = {
  [K in Foo as `key_${K}`]: any
}
/* type Baz = {
    key_a: any;
    key_b: any;
    key_1: any;
    key_2: any;
} */

For an instance involving iteration over a non-key type:

type KVPair = { k: "a", v: string } | { k: "b", v: number } | { k: "c", v: boolean };
type Qux = { [T in KVPair as T["k"]]: T["v"] };
/* type Qux = {
    a: string;
    b: number;
    c: boolean;
} */

This feature, unrelated to type assertions, offers significant utility.

Explore the code in TypeScript Playground

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

Error: Attempting to access a property called 'sign' on an undefined value

I encountered an issue while signing my transaction where I received an error message stating sendTransaction needs signer. Even though both message (encrypted using keccak256) and signer have values, I am unsure why there is a problem when executing the w ...

What is the best way to retrieve a value from an array of objects containing both objects and strings in TypeScript?

Consider this scenario with an array: const testData = [ { properties: { number: 1, name: 'haha' } , second: 'this type'}, ['one', 'two', 'three'], ]; The goal is to access the value of 'second&ap ...

Missing "this" after initialization? (typescript/node/express)

I am currently working on creating a basic http application using node-express. One issue I encountered is that when setting up routes, the constructor of the MyRouter class has access to this, but it seems to be lost within the getRoutes() function. cla ...

What is the best way to implement lazy loading for child components in React's Next.js?

I am exploring the concept of lazy loading for children components in React Next JS. Below is a snippet from my layout.tsx file in Next JS: import {lazy, Suspense} from "react"; import "./globals.css"; import type { Metadata } from &quo ...

Jest encounters issues while attempting to execute TypeScript test cases

Encountering an error while trying to execute tests in a repository that has a dual client / server setup. The error seems persistent and I'm unable to move past it. > jest --debug { "configs": [ { "automock": false, ...

Why does "excess property checking" seem pleased when I utilize a key from set A or set B, even though "keyof (A|B)" is consistently "never"?

I am diving deeper into Typescript types and encountering some puzzling behavior: interface Person { name: string; } interface Lifespan { birth: number; death?: number; } let k: keyof (Person | Lifespan); //k is never let test1: Person | Life ...

Yes, indeed - Entering the schema of a retrieved field from an Object schema

After deciding to upgrade from Yup version 0.29 to 1.2, I encountered some challenges with its types. Seeking assistance in finding the best solution for typing yup schemas. In version 0.29, the universal type Schema fit everywhere, but now it no longer d ...

Transform a 3D text rotation JavaScript file into an Angular component tailored TypeScript file

I have a javascript file that rotates text in 3D format, and I need help converting it into an Angular component specific TypeScript file. You can find the codepen for the original JavaScript code here. Below are my Angular files: index.html <!doctyp ...

Verifying input for Numeric TextField

The text field being used is: <TextField variant="outlined" margin="normal" id="freeSeats" name="freeSeats" helperText={touched.freeSeats ? errors.freeSeats : ''} error={touched.freeSeats && Boolean(errors.fre ...

Continuously apply the template in a recursive manner in Angular 2 without reintroducing any duplicated components

Recently, I delved into the world of angular 2 and found it to be quite fascinating. However, I'm currently facing a roadblock and could really use some assistance. The scenario is as follows: I am working on creating a select box with checkboxes in ...

Why is @faker-js/faker not usable in a TypeScript project, showing undefined error, while the older "faker" import still functions correctly?

Currently, my packages.json file includes: "faker": "^5.5.3", "@types/faker": "^5.5.3", I am sticking with version 5.5.3 due to another project dependency (codecept) that requires this specific version. The ...

Creating JPEG images with specified dimensions. How can you add W x H sizing to an image?

I have been searching for a Deno/TypeScript code snippet that can create basic images with dimensions embedded on them. I have provided an example of the code below, which generates images in JPEG format, base64, and dataURL. The code works by adding RGB ...

Using the input type 'number' will result in null values instead of characters

My goal is to validate a number input field using Angular2: <input type="number" class="form-control" name="foo" id="foo" [min]="0" [max]="42" [(ngModel)]="foo" formControlName="foo"> In Chrome, everything works perfectly because it ignores ...

Troubleshooting problems with permissions when using the AWS IAM assumeRole function with session

Within my aws-cdk application, I am working on setting up a lambda function to assume a specific role and obtain credentials through aws-sts. These credentials need to include a tenant_id tag. AWS CDK Code: Role to be assumed: const pdfUserRole = new Rol ...

The Keyup Filter in the FromEvent function is malfunctioning and not behaving as anticipated

I have created a simple search function for my app using the FromEvent KeyUp and debounceTime features as shown in the code below: <input matInput #inputSearch> @ViewChild('inputSearch', { static: false }) input: ElementRef; fromEvent(th ...

How can we strengthen the type checking when defining the sorting function for json properties?

When dealing with a json structure from a service that contains .attributes json values, I often find myself needing to sort either by id from the DTO or by several attributes from the IContactsAttributes. The microservice returns this specific structure: ...

Showcase pictures within an angular smart table

Is it possible to display images in a column within an ng smart table? We have several columns consisting mostly of data, with one column dedicated to displaying images. Following the ng smart table concept, I attempted to implement the code below which cu ...

Utilizing a navigation menu to display various Strapi Collection pages within a single Angular Component

I have set up a collection in Strapi called Pages and I am looking to display them in the same component using my Navigation Bar Component. However, I am unsure of how to achieve this. Currently, all the data from the Collection is being displayed like th ...

Using ag-Grid's cellEditor with object values for selection

Looking to choose a user from a list of users: User.ts export class User { constructor (public id: number, public userName : string){} } The column definition appears as follows: this.columns = [ {headerName: "Assigned", field:"user ...

Issue with Angular: Unable to locate a differ that supports the object '[object Object]' of type 'object'. NgFor is only compatible with binding to Iterables such as Arrays

As someone who is new to Angular, I am facing a challenge while working on my portfolio project. The issue arises when trying to receive a list of nested objects structured like this: "$id": "1", "data": { &quo ...