Typescript type definitions - understanding inheritance

My typescript interface defines the structure of my database data as follows:

interface Foo {
  bar: {
    fish: {
       _id: string,
       name: string,
    }[],
  },

  starwars: string[],
}

I want to be able to reference specific parts of this interface. For example, I want to pass the data under the key fish as parameters.

To achieve this, I initially created a new interface for Fish:

interface Fish {
  _id: string,
  name: string,
}

interface Foo {
  bar: {
    fish: Fish[],
  },

  starwars: string[],
}

function killTheFish(fish: Fish) { ... }

However, I am looking for a more concise way to accomplish this task. Is there a method to reference a specific part of an interface like in the following example?

type Fish = Foo.bar.fish;

If you have any insights on how to reference a part of an interface, please share!

Answer №1

A great solution for your query involves the use of lookup types, also known as indexed access types. Instead of dot notation (which could potentially cause conflicts with namespaces), this method utilizes square bracket notation:

type FishArray = Foo["bar"]["fish"]
/*
type FishArray = {
    _id: string;
    name: string;
}[]
*/

type Fish = Foo["bar"]["fish"][number];
/* type Fish = {
    _id: string;
    name: string;
} */

If you have a type T with properties and a key-like type K which is one of the keys of T (K extends keyof T), then T[K] represents the property type at key K within T. So if you access Foo["bar"]["fish"], you get the type of foo.bar.fish in an object of type Foo.

In your scenario, since it's an array example, you can extract the element type accordingly. Since arrays have a numeric index signature, using a key of type number will give you the element type. Hence, Foo["bar"]["fish"][number] denotes that specific element type.

I trust this explanation proves helpful to you. Best of luck!

Access Playground Here

Answer №2

Let's not delay any further - we have the ability to retrieve mapped type member types by index or key through lookup type syntax ['prop']

type BirdArr = Foo['bar']['bird'];

An array type can also be considered a mapped type Array<Y> = {[k:number]: Y}, where all keys are of type number. Just like extracting a member type from any other mapped type, we can use number for the elements in an array type

type Bird = Foo['bar']['bird'][number];

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

Issue with NgOnInit not properly subscribing to observable when using mockActivatedRoute in Jasmine test scenarios

Below is a simple component that I have. All necessary imports should be assumed: //my-component.component.ts //imports, decorator, etc. routingNumber: number; ngOnInit() { this.route.params.subscribe( params => { this.routingNumber = +p ...

Incorporate TypeScript @types/ packages within the packages.json file

I have a question about the @types dependencies in the package.json file: According to the information provided in this URL, it is suggested to install types as runtime dependency npm install --save @types/lodash TS 2.x d.ts Consumption However, personal ...

The module "node_modules/puppeteer/lib/types" does not contain the export "Cookie"

Currently facing an issue with puppeteer types. I am attempting to import the Cookie type, but it seems to be not functioning on versions above 6.0.0. import { Cookie } from 'puppeteer'; Here is the error message: /node_modules/puppeteer/lib/typ ...

Auth.js v5 now requires a manual page reload in order to display session data using the useSession() function. Experience seamless authentication with this update in

Currently in the process of developing a website using NextJS 14 and Auth.js v5. The issue I'm facing pertains to the settings page post user login redirection. Depending on whether the user logs in using OAuth like Github or with Credentials, there s ...

execute the NPM script in the current directory

Within my package.json file for a node project, I have the following test script that utilizes the ts-node package: "scripts": { "build": "tsc", "test": "ts-node" } Executing this script from the root ...

Tips for merging individual Koa-Routers using Typescript

My approach to organizing routers in my project involved categorizing them based on their purpose. Here's how they are structured: routers/homeRouter.ts import * as Router from 'koa-router'; const router: Router = new Router(); router ...

I encountered an issue with the date input stating, "The parameters dictionary includes a missing value for 'Fromdate' parameter, which is of non-nullable type 'System.DateTime'."

An error message is popping up that says: '{"Message":"The request is invalid.","MessageDetail":"The parameters dictionary contains a null entry for parameter 'Fromdate' of non-nullable type 'System.DateTime' for method 'Syste ...

Issue: Module '@nrwl/workspace/src/utilities/perf-logging' not found

I attempted to run an Angular project using nxMonorepo and made sure to install all the necessary node modules. However, when I tried running the command "nx migrate --run-migrations" in my directory PS C:\Users\Dell\Desktop\MEANAPP&bso ...

Retrieving a portion of the response with Angular's HttpRequest

I am facing an issue with a request where I need to upload a file and receive a JSON response. The problem arises when trying to access a specific part of the response, namely body.path. Despite my efforts, I keep encountering an error stating that the pat ...

Leverage the child interface as a property interface containing a generic interface

I'm facing an issue while trying to incorporate typings in React. The concept is centered around having an enum (EBreakpoint) that correlates with each device we support. A proxy wrapper component accepts each device as a prop, and then processes the ...

Creating a visually appealing stacked bar chart using Chart.js in Angular 9 with multiple bars

Upon integrating Chart.js into my Angular 9 application, I encountered an issue where the expected chart values were not being displayed. In order to address this problem, I need to structure the barChartData according to the format showcased in this stac ...

Utilizing puppeteer-core with electron: A guide

I found this snippet on a different Stack Overflow thread: import electron from "electron"; import puppeteer from "puppeteer-core"; const delay = (ms: number) => new Promise(resolve => { setTimeout(() => { resolve(); }, ms); }) ...

Exploring the benefits of using getServerSideProps with NextJS and Typescript for

Dear community, I am facing a challenge with integrating NextJS Layout and Typescript. Although everything seems to be working fine, I can't seem to get rid of the squiggly line under the props when passing them from getServerSideProps. The prop {som ...

What could cause a member variable to be uninitialized in the ngInit method in Ionic/Angular, even though it was initially set in the constructor

Despite setting the modal form to be bound to an instance of "Foo" during its construction, I encountered a strange issue where, post-constructor, this.foo became undefined. Even after verifying this through breakpoints and console.log, the problem persist ...

Arranging the output of a Typescript project

I'm currently advocating for Typescript to be implemented in our web application. Can anyone provide insight on the best method for structuring Javascript output files? Should they be excluded from source control? And when it comes to testing, is it p ...

How does the Paginate Pipe effectively retrieve the array length in an Angular 2 application?

I find myself in an interesting situation where I have a piece of code that is functioning within my Angular 2 application - it's generating the correct value, but the method behind its success is unclear to me. Specifically, I am using ng2-paginatio ...

Inversify employs dependency injection similarly to how Angular utilizes TypeScript decorators

Today I made the switch from a js electron project to typescript and found myself wondering about the equivalent of angular's dependency injection. Since Angular Universal is still in its early stages and lacks documentation on using it with electron ...

Is there a way to adjust the width of a table cell in Material UI using React?

I encountered a problem where I am attempting to adjust the width of a table cell, specifically in Typescript. However, I am only able to choose between medium and small sizes for TableCellProps. Is there a workaround for this issue? I am looking to expand ...

Leverage the power of a useRef hook to dynamically update a state value within React, even when the object is potentially

I'm running into an issue with the useRef hook, as I'm receiving the error "object is possibly null" when attempting to use it to set a stateful object. const jselectRef = useRef<HTMLButtonElement>(null) const [defaultHeight, setDefaultHeig ...

TSLint warning: Duplicate identifier detected - 'err'

Currently facing an issue with tslint displaying the following error Shadowed name: 'err' Providing the code snippet for reference fs.readdir(fileUrl, (err, files) => { fs.readFile(path.join(fileUrl, files[0]), function (err, data) ...