Ways to ascertain if a TypeScript type is a specific value

Can a utility type be created to identify whether a type is a literal value? For example:

type IsLiteral<T> ...

type IsStringALiteral = IsLiteral<string> // false
type IsStringLiteralALiteral = IsLiteral<'abc'> // true
type IsStringALiteral = IsLiteral<bool> // false
type IsStringLiteralALiteral = IsLiteral<false> // true

Answer №1

Check out this article on determining if a type is a 'string' literal, 'number' literal, or 'string | number' literal: Determine if type is a 'string' literal, 'number' literal or 'string | number' literal

type IsStringLiteral<T> = string extends T ? true : false;

type T = {
  true: true,
  123: 123,
  'text': 'text',
  string: string,
}
type X = {[K in keyof T]: IsStringLiteral<T[K]>}
// type X = {
//     true: false;
//     123: false;
//     text: false;
//     string: true;
// }

Answer №2

After some exploration, I've managed to solve the issue on my own:

type IsUnionCollection<T, U extends T = T> = T extends unknown ? ([U] extends [T] ? false : true) : false;
type IsStringText<A> = IsUnionCollection<A> extends true ? false : A extends string ? (string extends A ? false : true) : false;
type IsNumberValue<A> = IsUnionCollection<A> extends true ? false : A extends number ? (number extends A ? false : true) : false;
type IsBooleanValue<A> = IsUnionCollection<A> extends true ? false : A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteralValue<A> = IsStringText<A> extends true ? true : IsNumberValue<A> extends true ? true : IsBooleanValue<A> extends true ? true : false;

I incorporated IsUnionCollection functionality because I needed:

type IsStringUnionText = IsLiteralValue<'a' | 'b'> // false

If this doesn't meet your needs, here is an alternative approach:

type IsStringText<A> = A extends string ? (string extends A ? false : true) : false;
type IsNumberValue<A> = A extends number ? (number extends A ? false : true) : false;
type IsBooleanValue<A> = A extends boolean ? (boolean extends A ? false : true) : false;
type IsLiteralValue<A> = IsStringText<A> extends true ? true : IsNumberValue<A> extends true ? true : IsBooleanValue<A> extends true ? true : false;

Answer №3

If you're looking to differentiate between string types and literal types, this approach could be helpful:

type trueIfLiteral<T extends string> = string extends T ? false : true;

A literal type can be assigned to a string type, but not vice versa, which is why we use the constraint:

T extends string

Then we determine if a string is assignable to the type parameter:

string extends T ? false : true;

For more information, you can visit: Is it possible to get the value (not key) in a literal object as a literal, not its type (such as string) via mapped type in Typescript?

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

Display JSON data in a table format using Angular

I have received a JSON result that looks like this: { "discipline":"ACLS", "course": [ { "value":"ACLS Initial", "classes":"0", "students":"0" }, { "BLS":"CPR Inst ...

Vitest's behavior shows variance when compared to compiled JavaScript

Challenge Currently, I am developing a package that relies on decorators to initialize class object properties. The specific decorator is expected to set the name property of the class. // index.ts const Property = (_target: any, key: any) => { } cl ...

How can I utilize Pinia and TypeScript to set the State using an Action?

I have a Pinia + TypeScript store named user.ts with the following structure: import { User } from 'firebase/auth'; import { defineStore } from 'pinia'; export const useUserStore = defineStore('user', { state: () => ( ...

Tips for simulating behavior in express using Typescript and the Mocha library

Help with mocking 'Request' in Mocha using express with Typescript needed! Here is the current approach: describe("Authorization middleware", () => { it("Fails when no authorization header", () => { const req = { ...

Anticipating the outcome of various observables within a loop

I'm facing a problem that I can't seem to solve because my knowledge of RxJs is limited. I've set up a file input for users to select an XLSX file (a spreadsheet) in order to import data into the database. Once the user confirms the file, v ...

Using ngIf for various types of keys within a JavaScript array

concerts: [ { key: "field_concerts_time", lbl: "Date" }, { key: ["field_concert_fromtime", "field_concert_totime"], lbl: "Time", concat: "to" }, { key: "field_concerts_agereq", lbl: "Age R ...

Tips for creating an Angular component that can receive a single value from a choice of two different lists

My angular component requires a value that belongs to one of two lists. For example: @Input() public type!: enumA | enumB; However, this setup becomes problematic when the enums share values or are linked together in a way I find undesirable. I would pre ...

Issue with the close button on ngb-alert not functioning properly

As I develop my website, I have incorporated an ngb-alert component to display an alert message to users upon login. While the alert itself is functioning properly, I have encountered an issue with the close button being misaligned, and I am struggling to ...

Can a string array be transformed into a union type of string literals?

Can we transform this code snippet into something like the following? const array = ['a', 'b', 'c']; // this will change dynamically, may sometimes be ['a', 'e', 'f'] const readonlyArray = arr ...

Typescript: create a type similar to keyof but with a particular value type

I have an interface called MyInterface interface MyInterface { field1: boolean, field2: MyType, field3: MyType } In this interface, I want to create a new type that contains only the keys which have values of type MyType. While I know about the key ...

Creating an array of objects data is a breeze with Vue.js

I have an array of data containing selected items, and I need to extract the IDs from this array into a new array so that I can send only the IDs to the back-end. Sample Code method toggleSelection(rows) { console.log('this.multipleSelection : &a ...

Experiencing a useContext error when implementing MDX with NextJS 13

I am currently working on integrating mdx files into Next.js 13. After completing all necessary configurations in next.config and creating the file structure, I have the following path within the app folder: > docs > components > accordion > pa ...

What is the significance of the 'this' context type void not being assignable to type rule?

Currently, I am conducting tests using Typescript to explore the feasibility of a project I have in mind. In one of my functions, I need to specify the type of 'this' as a class. While it technically works, I continue to encounter an error messag ...

The argument provided is a string type, which cannot be assigned to a parameter expecting an object with a 'results' property of type string

When attempting to pass the result.nativeEvent.message to another function, I am encountering the error: Argument of type 'string' is not assignable to parameter of type '{ results: string; } on onUnityMessageController(result.nativeEvent.me ...

Making a synchronous call to a web API using JQuery

Understanding JQuery promises and deferred objects has been a bit of a challenge for me, so please bear with me. I should also mention that my application is built using React, Typescript, and ES6. Let's imagine we have an array of objects: [{ Objec ...

Customizing Material UI Select for background and focus colors

I am looking to customize the appearance of the select component by changing the background color to "grey", as well as adjusting the label and border colors from blue to a different color when clicking on the select box. Can anyone assist me with this? B ...

The i18next module encounters compilation issues when used in a React application with Typescript

In my React-Typescript project, I recently set up i18next for multi-language support. Despite following the official documentation guidelines, I encountered compilation errors when running the app: Property 'changeLanguage' does not exist on type ...

Tips for activating scrolling on a background element even with a modal window currently displayed

Encountering an issue with Angular and Material for Angular - my application contains multiple modals that disable background scrolling when opened. However, there is one notification modal that should not block the background scroll. Despite not having a ...

Utilizing mapped types in a proxy solution

As I was going through the TS Handbook, I stumbled upon mapped types where there's a code snippet demonstrating how to wrap an object property into a proxy. type Proxy<T> = { get(): T; set(value: T): void; } type Proxify<T> = { ...

Iterate over Observable data, add to an array, and showcase all outcomes from the array in typescript

Is there a way to iterate through the data I've subscribed to as an Observable, store it in an array, and then display the entire dataset from the array rather than just page by page? Currently, my code only shows data from each individual "page" but ...