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
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.
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!
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; }
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, };
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With