Getting To Know The Partial Type in TypeScript

 https://netbasal.com/getting-to-know-the-partial-type-in-typescript-ecfcfbc87cb6

I don’t usually bother to write about such small things, but I’ve come across many people who don’t know this handy feature, so I decided I should.

Let’s say we have a UserModel interface:

interface UserModel {
email: string;
password: string;
address: string;
phone: string;
}

And a User class with update() method:

class User {
update( user: UserModel ) {
// Update user
}
}

The problem with the code above is that we must pass an object that implements the whole UserModel interface, otherwise typescript will be 😡.

But in our case, we want to be dynamic and not be committed to the entire interface, but still get IntelliSense.

TypeScript (v2.1) provides us with a solution precisely for these cases — The Partial interface. All we need to do is to change the code above to this:

class User {
update( user: Partial<UserModel> ) {
// Update user
}
}

Now we can have the best of both worlds.

Another useful example would be if you have a component that takes configuration object as Input() and you want to have a default value.

type ComponentConfig = {
optionOne: string;
optionTwo: string;
optionThree: string;
}
export class SomeComponent { private _defaultConfig: Partial<ComponentConfig> = {
optionOne: '...'
}
@Input() config: ComponentConfig;

ngOnInit() {
const merged = { ...this._defaultConfig, ...this.config };
}
}

Under the hood the Partial interface looks like this:

type Partial<T> = { [P in keyof T]?: T[P]; };

You can read more about the keyof feature here.

https://stackoverflow.com/questions/54986332/typescript-class-extending-partial-interface


The problem is that Partial<T> will only allow you to implement the members will not require you to do so, and if you don't implement the member it will not be in the class.

You can create a function that returns a class and this class will implement the interface. The returned class will not actually have to declare any of the fields so they will all be undefined but this should be fine since the fields have to be optional anyway.

interface Animal {
    name: string;
}

type OptionalAnimal = Partial<Animal>;
function autoImplement<T>(): new () => T {
    return class { } as any;
}
class Dog extends autoImplement<OptionalAnimal>() {
    public constructor() {
        super();
    }
    public breed: string;
}

var spot = new Dog();

spot.name = "Spot"; // ok now

You can also cast the Dog class to specify that the returned instance has the members of Animal but these new members will not be accessible from inside the class:

interface Animal {
    name: string;
}

class _Dog {
    public constructor() {

    }
    public breed: string;
}

const Dog = _Dog as { new(): _Dog & Partial<Animal> } & typeof _Dog
type Dog = InstanceType<typeof Dog>

var spot = new Dog();

spot.name = "Spot"; 

Không có nhận xét nào:

StaticImage

  import React , { useEffect , useRef } from "react" import { StaticImage } from "gatsby-plugin-image" impor...