Potential keys + keys that are present in the `initialData`

Is there a way to specify the type of data in order to include all keys that exist in initialData plus additional keys from Item as Partial(optional)?

class TrackedInstance<Item extends Record<string, any>, InitialData extends Partial<Item> = Partial<Item>>> {
  private _data: Partial<Item> = {}

  constructor(initialData: InitialData, isNew?: boolean) {
    this._data = initialData
  }

  get data() {
    return this._data
  }
}

interface User {
  name: string
  age: number
  isAdmin: boolean
}

const userInstance = new TrackedInstance<User>({
  name: ''
})

const test1: string = userInstance.data.name // Should be ok
const test2: number = userInstance.data.age // Should throw an error because age can be 'undefined' or 'number'

Ts playground

I believe it should look something like get data(): Pick & Partial> {

However, it gives an error:

TS2344: Type 'keyof InitialData' does not satisfy the constraint 'keyof Item'.

Answer №1

It is uncertain whether achieving this without using multiple functions is feasible.

An issue with TypeScript generics is that when one generic is specified, all others must also be specified. With generics that have default values, specifying one parameter will automatically set the others to their default value. Hence, TrackedInstance<User> enforces it to be

TrackedInstance<User, Partial<User>>
.

User jcalz raised this concern in the comments regarding interference of generic parameters for non-specified ones.

As mentioned, achieving this might require utilizing multiple functions to work around the "default generic value" issue, as shown by the solution involving multiple function calls:

class TrackedInstance<Item extends Record<string, any>, InitialData extends Partial<Item> = Partial<Item>> {
    private _data: InitialData;

    constructor(initialData: InitialData, isNew?: boolean) {
        this._data = initialData
    }

    get data(): InitialData {
        return this._data
    }
}

interface User {
    name: string
    age: number
    isAdmin: boolean
}

function track<T>() {
    return function <D extends Partial<T>>(initialData: D, isNew?: boolean) {
        return new TrackedInstance<T, D>(initialData, isNew);
    };
}

const userInstance = track<User>()({
    name: ''
})

const test1: string = userInstance.data.name // Should ok
const test2: number = userInstance.data.age // Should error because age can be 'undefined' | 'number'

Note that I had to adjust the type of your _data to be InitialData instead of just Partial<Item>. The code above results in the intellisense/error displayed below:

https://i.stack.imgur.com/Bg0Pn.png

In this case, .data only represents InitialData. If you also want "partial access" to the rest of the data, modify the type of your private _data field to be

InitialData & Partial<Item>
.

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

Ionic 2 encountering issue with `ctorParameters.map` not being a function error

Recently, I wanted to incorporate the Network-information plugin into my project but encountered compatibility issues with an older version of Ionic-native. To resolve this, I took the following steps: npm rm --save ionic native npm install --save ionic-n ...

Typescript's identification of a dispute between RequireJS and NodeJS definitions

I obtained the Typescript RequireJS definition from Definitely Typed. It includes an ambient declaration of Require that clashes with the NodeJs command "require". See below for the declaration and the error message: Declaration: declare var require: Req ...

Submitting an image blob to a database using the FormBuilder

I'm facing an issue with uploading a file blob into the same DB as my form. Here is my form: this.accForm = this.formBuilder.group({ team_leader: ['', Validators.required], hotel_name: ['', Validators.required], address: [&a ...

After triggering an action, I am eager to make a selection from the store

To accomplish my task, I must first select from the store and verify if there is no data available. If no data is found, I need to dispatch an action and then re-select from the store once again. Here is the code snippet that I am currently using: t ...

Understanding type inference in TypeScript

I'm attempting to grasp the concept of inferring generics in Typescript, but I can't seem to figure out where I'm going wrong. Although my concrete example is too large to include here, I've provided a link to a small TypeScript playgro ...

I am sorry, but it seems like there is an issue with the definition of global in

I have a requirement to transform an XML String into JSON in order to retrieve user details. The approach I am taking involves utilizing the xml2js library. Here is my TypeScript code: typescript.ts sendXML(){ console.log("Inside sendXML method") ...

Angular 4 and the process of HTML encoding

Looking for assistance with html encoding in angular 4. I have product records stored in a database, with the fullDescription field in this particular format: &lt;div align="justify"&gt;&lt;span&gt; When using <div *ngIf="product" [inn ...

Implementing a NextJS client component within a webpage

I am currently working with NextJS version 14 and I am in the process of creating a landing page. In one of the sections, I need to utilize the useState hook. I have specified my component as "use-client" but I am still encountering an error stating that " ...

Utilizing React with .NET 8.0 and Minimal API, the front end is configured to send HTTP requests to its own specific port rather than the

Transitioning from working with react projects on .NET 3.1 to creating a new project on .NET 8.0 has been a challenging and confusing experience for me. When I attempted to access a newly created controller method, I encountered the error 404 Not Found. It ...

Is it possible to define data types for the global context in cucumber?

Embarking on a fresh cucumber-selenium project in Typescript, I am eager to keep the Driver in the world context. However, following the method suggested here, I encounter an issue where the Driver type remains inaccessible to step definitions. This means ...

Why is my Angular Reactive form not retrieving the value from a hidden field?

I've encountered a problem where the hidden field in my form is not capturing the product id unless I manually type or change its value. It consistently shows as "none" when submitting the form. TS https://i.stack.imgur.com/W9aIm.png HTML https://i. ...

What is the best way to include a select HTML element as an argument in an onSubmit form function call?

I am currently facing an issue where I am attempting to pass HTML elements of a form through the submit function as parameters. I have been able to successfully retrieve the nameInput element using #nameInput, but when trying to access the select element ( ...

How can I transform this statement into a higher-order function that offers a resource instead of using an object for initialization and destruction?

Starting with this code snippet: convert utilizes svgInjector to start and terminate a resource. export async function convert( serializedSvg: string, svgSourceId: string, containerId: string ): Promise<string> { const svgInjector = new SvgI ...

Experiencing a compilation issue while attempting to apply the class-transformer

Encountering an issue while working with a basic example that involves class-transformer. error TS1240: Unable to resolve signature of property decorator when called as an expression. Argument of type 'ClassFieldDecoratorContext<Root, Project[]> ...

What is the method for transmitting a URL API from an ASP.NET Core server to my Angular 2 single application?

Is there a way to securely share the url of the web api, which is hosted on a different server with a different domain, from my asp net core server to my client angular2? Currently, I am storing my settings in a typescript config file within my angular2 ap ...

What is the recommended TypeScript type for the NextJS _app.tsx Component and pageProps?

Take a look at the default _app.tsx code snippet from NextJS: function MyApp({ Component, pageProps }) { return ( <Component {...pageProps} /> ) } The issue arises when transitioning to TypeScript, as ES6Lint generates a warning indicating t ...

The property 'toLowerCase' cannot be accessed as it is undefined or null

Scenario: A textbox is present with a list of data below it. Upon typing in the textbox, the list gets filtered based on the text entered. Code: Pipe: @Pipe({ name: 'search' }) export class SearchPipe implements PipeTransform { transform( ...

What is the solution to the error message stating that the property 'pipe' is not found on the OperatorFunction type?

I implemented the code based on RxJS 6 documentation while working with angular 5, RxJS 6 and angularfire2 rc.10. However, I encountered the following error: [ts] property 'pipe' does not exist on type 'OperatorFunction<{}, [{}, user, str ...

How can I restrict the highest possible date selection in reactjs?

I am working on a project that requires users to select dates using datetime-local, but I want to limit the selection to only three months ahead of the current date. Unfortunately, my current implementation is not working as expected. Any assistance woul ...

Is there a way to reset useQuery cache from a different component?

I am facing an issue with my parent component attempting to invalidate the query cache of a child component: const Child = () => { const { data } = useQuery('queryKey', () => fetch('something')) return <Text>{data}& ...