Tips for triggering an error during compilation for parameters lacking "as const"

Is there a way to generate a compile-time error if an argument is provided without being 'casted' as `const` in TypeScript? In the example code below, the array is converted into a `readonly` array:

function myFunc<T extends string[]>(arr: T): T {
    return arr;
}

const a = myFunc(["koo"] as const);
// Good, `a` is now `const a: ["koo"]`
// Should work


const b = myFunc(["koo"]); 
// Bad, `b` is now `string[]`
// Should throw, something like:
// TypeScript error: Argument of type 'string[]' is not assignable to parameter of type 'readonly string[]'

Answer №1

It's quite challenging to enforce the use of a `const` assertion (`as const`) in a function call. One could attempt to create a complex mechanism to reject `string[]`, but this approach would be delicate and prone to edge cases.

Alternatively, a better solution would be to utilize a `const` type parameter, specifying that function calls should be treated as if the user had used `as const`. Example:

function myFunc<const T extends string[]>(arr: T): T {
    return arr;
}

const a = myFunc(["koo"] as const);
// const a: ["koo"]

const b = myFunc(["koo"]); 
// const b: ["koo"]

Both calls will now behave as intended. However, it is still possible for someone to input non-literal values:

const z = ["koo"];
// const z: string[]
const c = myFunc(z);
// const c: string[]

In such cases, it is not possible to write `myFunc(z as const)`. Therefore, using a `const` type parameter serves the same purpose as a `const` assertion.

Link to Playground with code example

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

Transfer an Array of Objects containing images to a POST API using Angular

Looking to send an array of objects (including images) to a POST API using Angular and Express on the backend. Here's the array of objects I have: [{uid: "", image: File, description: "store", price: "800"} {uid: "f ...

Discovering the right category for a general component: A step-by-step guide

How about creating a new list component that can work with an array of objects? <script setup lang="ts"> const props = defineProps<{ items: Record<string, unknown>[], selected: Record<string, unknown> | null field: stri ...

The type definition file for 'node' cannot be located

I've encountered some unusual errors after updating angular, webpack, and typescript. Any suggestions on what might be causing this? When I attempt to run the application with npm start, I'm seeing the following errors: [at-loader] Cannot find ...

Sort the array based on the enum name rather than its value

Below is an example of an enumeration: export enum Foo { AA = 0, ZZ = 1, AB = 2, ER = 5 } In my case, I want to sort my Bars based on the name of the enum (AA, AB, ER, ZZ), rather than the numerical value (0, 1, 2, 5) that they represent. ...

What is the best way to provide JSON data in Angular?

I am working on an Angular 4 application that is using Webpack, and I am currently facing a challenge with serving a JSON file. I have two main questions regarding this: When the JSON file is static, I am struggling to configure Webpack to handle it the ...

When exporting a custom ES6 module and importing it into a different local project, you may encounter unexpected outputs such as being undefined or

Currently, I am using TypeScript 3.4.5 and Webpack 4.32.2 on Windows 10 via WSL. My goal is to create a local package of tools that consolidates basic classes into an index file for exporting. However, when I try to import these classes into other project ...

Utilizing Vue and Typescript for efficient dependency injection

After attempting to use vue-injector, I encountered an issue as it was not compatible with my version of Vue (2.6.10) and Typescript (3.4.5). Exploring other alternatives, there seem to be limited options available. Within the realm of pure typescript, t ...

Performing a search through a string array and updating a specific portion of each string

I am faced with an array containing a long list of Strings, and my goal is to filter out all the strings that begin with 'INSERT ALL' and replace the number inside the parentheses with the string ' NULL' Here is the original array: le ...

Blend the power of Node's CommonJS with the versatility of Typescript's ES modules

I currently have a Node.js v10 legacy application that was built using CommonJS modules (require). The entire codebase is written in JavaScript. However, I am considering upgrading the app and refactoring a specific part of it to use TypeScript modules ( ...

Error alert: TypeScript typings issue - Naming conflict with Promise / Failure to locate name Promise

I am currently working on a client/server JavaScript application and I am facing a significant issue with Promises. It appears that they are either undefined or duplicated, and this problem seems to be related to the @types package. npm install --save @ty ...

Do you notice a discrepancy in the number returned by Javascript's Date.getUTCDate() when the time component is set to

Consider the following code snippet: const d = new Date('2010-10-20'); console.log(d.getUTCDate()); If you run this, the console will output 20. However, if you modify the code like so: const d = new Date('2010-10-20'); d.setHours(0, ...

What are the optimal strategies for managing various components within an Angular (2) Web application?

I am seeking advice on Angular 2+ Webapps and have a few questions. What is the recommended approach for managing a publicly available info page, an authentication page, and a protected page for signed-in users? Should I consider separate Angular Apps ...

Whenever a call to `http.put` is made, it is certain that

I am facing an issue with my form in Angular 2. When the user clicks on the submit button, I intend to send the data to a rest endpoint using the http module. Here is the structure of the form: <form novalidate [formGroup]="formGroup()" (ngSubmit)="sen ...

Is there a way to utilize the 'interval' Rxjs function without triggering the Change Detection routine?

My goal is to display the live server time in my application. To achieve this, I created a component that utilizes the RXJS 'interval' function to update the time every second. However, this approach triggers the Change Detection routine every se ...

Simulating Express Requests using ts-mockito in Typescript

Is there a way to simulate the Request class from Express using ts-mockito in typescript? I attempted the following import { Request, Response } from "express"; const request = mock(Request); const req: Request = instance(request); but encou ...

Make the switch from TypeScript namespaces to ES2015 modules

After making adjustments to my TypeScript configuration, I am now encountering errors related to the no-namespace rule. Here is how my current setup involving namespaces looks like: Exporting classes within a namespace: namespace MyNamespace { export ...

Troubleshooting Axios errors when using createAsyncThunk function

Can someone help me with handling errors in createAsyncThunk using TypeScript? I attempted to declare the returned type and params type with generics, but when it came to error handling typing, I found myself resorting to just using 'any'. Let& ...

Angular 2 and beyond: Accessing a child element using @ViewChild()

Is it possible to access the child elements (specifically <img>) of @ViewChild() in Angular 2+ without explicitly declaring them? Within template.html <div #parent> <!-- Other elements besides <img> can also be present --> < ...

Combine the object with TypeScript

Within my Angular application, the data is structured as follows: forEachArrayOne = [ { id: 1, name: "userOne" }, { id: 2, name: "userTwo" }, { id: 3, name: "userThree" } ] forEachArrayTwo = [ { id: 1, name: "userFour" }, { id: ...

Updating a component in Angular 4.3.1 from within an observable callback

My Project Journey I am currently immersing myself in learning Angular by working on a personal project: developing a game that involves routing, services, and more. One of the requirements is to hide the header on the landing page (route for '/&apos ...