Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript remove optional property

I'm trying to build a dynamic type for a builder

export type Builder<T, K extends keyof T> = {
    [P in K]: (value: T[P]) => Builder<T, K>;
} & {
    build(): Readonly<T>;
};

If I have a class or an interface with optional properties, I get this kind of error:

$ tsc
test/OtherClass.ts:29:1 - error TS2722: Cannot invoke an object which is possibly 'undefined'.

29 OtherClass.builder().patate(Patate.AU_FOUR).build();
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is my class

export class OtherClass {
    constructor(
        public literal: string | undefined,
        public patate?: Patate,
        public hello: Readonly<Hello> = {},
    ) { }

    static builder: () => Builder<OtherClass, keyof OtherClass> = builder.for(OtherClass);
}

I was expecting the type to create a builder with a non-optional method for each properties, but for some reason, the optionality of patate seem inherent to the key and not the type. I don't get this behavior with the property literal

It looks like an issue to me. I'm using typescript 3.1.4. Is there another way to remove the question mark dynamically?

I've tried to use the NonNullable helper to create first a copy of my type with nothing nullable, but patate remains optional.

This is the effective type that vscode gives me

(property) patate?: ((value: Patate | undefined) => Builder<OtherClass, "literal" | "patate" | "hello">) | undefined
like image 217
Francis Avatar asked Nov 15 '18 03:11

Francis


People also ask

How do I delete a properties in TypeScript?

To remove a property from an object in TypeScript, mark the property as optional on the type and use the delete operator. You can only remove properties that have been marked optional from an object.

How to remove property from interface TypeScript?

Use the Omit utility type to remove a property from an interface, e.g. type WithoutAge = Omit<Person, 'age'> . The Omit utility type constructs a new type by removing the specified keys from the existing interface. Copied!

What is optional property in TypeScript?

Optional property: In Typescript you can declare a property in your interface which will be optional. Suppose you have a interface for employee and middle name is optional then your code will look like this: interface IEmployee { firstName: string; lastName: string; middleName?: string; }

How do I use omit TypeScript?

The TypeScript Omit utility type It will remove the fields you defined. We want to remove the id field from our user object when we want to create a user. type UserPost = Omit<User, 'id'>; const updateUser: UserPost = { firstname: 'Chris', lastname: 'Bongers', age: 32, };


1 Answers

Does this help?

export type Builder<T, K extends keyof T> = {
    [P in K]-?: (value: T[P]) => Builder<T, K>;
} & {
    build(): Readonly<T>;
};

Note the -? which does what you want - removes optionality.

like image 155
Nurbol Alpysbayev Avatar answered Nov 15 '22 11:11

Nurbol Alpysbayev