Is it possible to "retrieve" the TypeScript interface property type in any way?

Imagine a scenario where there is a typing file for library X that contains some interfaces.

interface I1 {
    x: any;
}
    
interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

When working with this library, it becomes necessary to pass around an object of exactly the same type as I2.y. One option is to create an identical interface in the source files:

interface MyInterface {
    a: I1,
    b: I1,
    c: I1
}

let myVar: MyInterface;

However, this approach introduces the burden of keeping it in sync with the library's interface, leading to potential code duplication and maintenance overhead.

Is there a way to "extract" the type of this specific property from the interface? Perhaps something like let myVar: typeof I2.y (which currently results in a "Cannot find name I2" error).


Edit: After experimenting in TS Playground, it was discovered that the following code achieves the desired outcome:

declare var x: I2;
let y: typeof x.y;

However, this method requires declaring a redundant variable x. The goal is to find a solution without the need for this declaration.

Answer №1

Previously impossible, but now made achievable with the release of TypeScript version 2.1 on December 7th, 2016. This update brings in indexed access types, also known as lookup types.

The new syntax resembles element access but is used for defining types. For example:

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

let myVar: I2['y'];  // indexed access type

With this, myVar takes on the type of I2.y.

Experiment with it on the TypeScript Playground.

Answer №2

Further elaborating on the approved response, you also have the option to specify the type using the keyword type and utilize it in various contexts.

// An example of a lesser-known library
interface A {
  prop: {
    name: string;
    age: number;
  }
}

// Defining your custom type
type A_Prop = A['prop']

// Implementation
const myThing: A_prop = { name: 'June', age: 29 };

Answer №3

Here is a demonstration of how to extract a literal type from a union object type:

type Settings = {
    option: "theme",
    value: string,
} | {
    option: "language",
    value: string,
}

export type SettingOption = Settings["option"];
// "theme"|"language"

Answer №4

keyof Colors will provide a collection of keys such as

"white" | "black"
. Once these keys are used in the Colors interface, the resulting type will consist of all the corresponding values, "#fff" | #000.

interface Colors {
  white: "#fff"
  black: "#000"
}

type ColorValues = Colors[keyof Colors]
// ColorValues = "#fff" | "#000"

Answer №5

function createObject() {
  return {title: "example", number: 7}
}
type Result1 = ReturnType<typeof createObject> // {title: string, number: number}
type Result2 = ReturnType<typeof createObject>['title'] // string
type Result3 = Result1['number'] // number

Answer №6

An interface serves as the blueprint for an object. In this case, y represents a property of your I2 object with a specific type, in this instance "anonymous".

To define y using another interface, you can create a separate interface called ytype and then use it as the type for y like so:

interface ytype {
   a: I1;
   b: I1;
   c: I1;
}

interface I2 {
    y: ytype;
    z: any;
}

You have the option to store your interfaces in a file and utilize extraction to allow them to be imported into other files within your projects.

export interface ytype {
   a: I1;
   b: I1;
   c: I1;
}



 export interface I2 {
        y: ytype;
        z: any;
    }

To import them, you can do the following:

   import {I1, I2, ytype} from 'your_file'

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

Defining generic types for subclasses inheriting from an abstract class containing type variables in TypeScript

Within my abstract class Base, I utilize a type variable <T> to define the type for the class. I have numerous derived classes that explicitly specify the type, like class Derived extends Base<string> {...} I aim to have a variable (or an arra ...

What is the best way to swap out the if else statement with a Ternary operator within a JavaScript function?

Is there a way to replace the if else statement in the function using a Ternary operator in JavaScript? private getProductName(productType: string): string { let productName = 'Product not found'; this.deal.packages.find(p => p.isSele ...

Troubles with Declaration Merging in Angular 2 Implementation

I'm currently working on incorporating a custom RxJS operator into my project, following the steps outlined in this particular answer. Below are the relevant code snippets from my application: rxjs-extensions.ts import { Observable } from 'rxjs ...

Challenge with Google Maps Data Layer

I am currently facing challenges with implementing the Google Maps React API and navigating through the Google Maps documentation. My goal is to display a polygon on the map and perform various manipulations. Here's what I have accomplished so far. I ...

The function passed as a prop is unrecognized

I am having an issue with passing the function toggle and it is showing as undefined. Any advice on how to resolve this? function page() { const [open, setOpen] = React.useState(false); const handleToggle = () => { setOpen(!open); }; ...

Guide on enabling a new property within an Interface containing a nested array

Within my interface, there is a property named data which contains an array. The structure looks like this: type Data = { prop1: string; prop2: string }[]; interface MyInterface { prop1: string; data: Data; } Now, I have an RxJS stream where the typ ...

The properties required for type 'never[]' are not present

The type 'never[]' does not have the necessary properties from type '{ login: string; id: number; node_id: string; avatar_url: string; url: string; }': login, id, node_id, avatar_url, url When working on a component that takes an ApiUr ...

Obtain the object literal string with additional decorative strings surrounding it

In my current Typescript code, I have an object literal structured like this: const MyNamesStrings = { a: { b: "hello", c: "bye" } d: { e: "qwerty" } } However, I am looking for a way to wrap these strings with add ...

The Java value is not returned by the Observable<boolean> stream

I'm currently working on making a request to the backend for a boolean value using observables, but I'm struggling to figure out the best approach between .map and .subscribe. return this.http.put({url}, credentials, this.requestOptions) .ca ...

How can I leverage the data fetched from API in Angular 13?

Just dipping my toes into the world of Angular by creating a quiz app to gain some hands-on experience. Successfully receiving a random set of questions from the API, but now facing the challenge of iterating over this array to implement the gameplay. The ...

Steps for preloading a user prior to the page loading

Main Concern I currently have an Auth Provider set up in my application that wraps around the entire _app.tsx file. This allows me to utilize the "useAuth" hook and access the user object from any part of the app. However, I am facing an issue when using ...

Transferring information between components without relying on @Input and @Output properties

I am currently in need of a system that functions like a "shopping cart" for one component within my site. It will essentially be a list of user-generated needs collected while they browse. Although this system won't involve pricing or tax calculation ...

An issue has occurred with attempting to access the 'phone' property of a null value. This error is at the root of the problem and needs to

I have implemented a function to retrieve all clients from an API: this.ws.getallclients().subscribe( client => { this.client = client.map((clients) => { this.filteredOptions = this.addsale.controls['client_id'].valueChanges. ...

I keep encountering errors with TypeGuard

Looking for some guidance with typescript. Even after implementing a type guard (and including the '?' symbol), I'm still encountering errors in the code snippet below. Is the syntax correct or should I make changes to the tsconfig file? int ...

Discover the process of retrieving all workday dates using Angular

Currently, I am working on a project in Angular that involves allowing employees to record their work hours. However, I am facing a challenge in figuring out how to gather all the work dates and store them in an array. Here is what I have attempted so fa ...

The data type 'StaticImageData' cannot be converted to type 'string'

I've hit a roadblock with interfaces while working on my NextJS and TypeScript project. I thought I had everything figured out, but I'm encountering an issue with the src prop in my Header component. The error messages I keep receiving are: Typ ...

Create an instance of a TypeScript class within an Angular HTML template

Can TypeScript and Angular (6) be used in conjunction for this question? Here is a model class example: export class DropData { private readonly _originType: Component; private readonly _originRow: number; private readonly _originCol: number; ...

Changing byte array to image in Angular 6

I have received the image file as a byte array from the server. My next step is to convert it into a jpeg file and then display it on a webpage. Here's the code: app.get('/getPhoto/:hash',function(req, res){ console.log(req.params.hash ...

The error states that the type '() => string | JSX.Element' cannot be assigned to the type 'FC<{}>'

Can someone help me with this error I'm encountering? I am fairly new to typescript, so I assume it has something to do with that. Below is the code snippet in question: Any guidance would be greatly appreciated. const Pizzas: React.FC = () => { ...

Implementing conditional where clauses in Firestore queries with dynamic parameters

Consider this scenario: I have a dynamic filter list for my product list, and I want to send an HTTPS request to a cloud function based on the selected filters. However, when trying to set multiple conditional where clauses from that request... The multip ...