How to make all the attributes of a class selectable?
For example, I have the following type:
type User = {
username: string;
gender: 'male' | 'female';
age: number;
bio: string;
password: string;
}
User
type requires that all attributes must have values, so:
const user: User = {
username: 'awesomeuser',
};
Is not feasible, it will prompt:
类型“{ username: string; }”缺少类型“User”中的以下属性: gender, age, bio
How to make it feasible? Use Partial
to:
const user: Partial<User> = {
username: 'awesomeuser'
}
Partial
built-in inner type is to make all the attributes of a defined type optional. The specific implementation is as follows:
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
How to make all attributes of a type mandatory?
Suppose we have the following type definition:
type User = {
username: string;
age?: number;
gender?: 'male' | 'female'
bio?: string;
password?: string;
}
Then got a series of user data results from the server backend:
const users: User[] = await api.users.list();
At this point, we try to access the user's age
for comparison, and want to retrieve the user age > 18
const filteredUsers = users.filter(user => user.age > 18);
At this time, does your IDE prompt you: object may be "undefined". ? Why? Because we defined
age
itself as an optional attribute, when the attribute is not defined, its value is undefined
, and in typescript
, undefined
is not allowed to number
type, but at this time we can actually be sure api.users.list
Interface returned to me, either throw an error or give to me it must be brought age
value User
type of data, so I can compare to, but because TypeScript
do not know if the data you are loading User
User
with all attributes already have values, what should I do? What Required
do.
const users: Required<User>[] = [];
Or let api.users.list()
return type is Required<User>[]
can be.
How to implement Required
:
/**
* Make all properties in T required
*/
type Required<T> = {
[P in keyof T]-?: T[P];
};
How to make all attributes of a type read-only?
Suppose we are writing a system now. When the user logs in, we will share a User
object to all components, but only allow others to read its value and not allow others to modify it, but the User
we defined is shared by the entire system and has editing functions. Pages are also using this type definition, they need to be able to modify user data, what should I do?
Use Readonly
to:
const user = {
username: "awesomeuser",
gender: "male",
age: 19,
bio: "Aha, insight~",
};
const sharedUser = user as Readonly<User>;
sharedUser.username = "new Name";
At this point, the IDE will tell you that cannot be assigned to "username" because it is a read-only attribute.
Note that : TypeScript only performs static type checking, but it does not mean that these values cannot be modified. If you really want to create an object that cannot be modified programmatically, how can I solve it?
I want to have a class that only has some attribute definitions of another class
Still the User
, I want to define a Login
, which is specifically used for the type when logging in, but I don’t want to password
username
and 0613b10949d24e (although in this example, it is easy to rewrite it, but it is not the same. Someday will you encounter a very complicated type definition?), what should I do? Use Pick
.
type User = {
username: string;
gender?: "male" | "female";
age?: number;
bio?: string;
password?: string;
};
type Login = Pick<User, "username" | "password">;
const login: Login = {
username: "pantao",
};
As you can see, the Login
or only username
is required, and password
is optional. This does not meet our requirements. What should I do? Add Required
.
type User = {
username: string;
gender?: "male" | "female";
age?: number;
bio?: string;
password?: string;
};
type Login = Required<Pick<User, "username" | "password">>;
const login: Login = {
username: "pantao",
};
You will be asked to enter password
at this time.
How to implement Pick
?
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
If you quickly define a type, attributes with the same data type?
Suppose we are currently developing a mall system, and each Store
has a store manager, a warehouse manager, and a cashier. They are all associated with User
. At this time, you can define the type Store
type User = {
username: string;
gender?: "male" | "female";
age?: number;
bio?: string;
password?: string;
};
type Store = {
name: string;
location: string;
leader: User;
warehouseKeeper: User;
cashier: User;
};
Of course, you can also define it like this:
type Store = Record<'leader' | 'warehouseKeeper' | 'cashier', User> & {
name: string;
location: string;
}
Which of the two methods is better, of course, has its own advantages and disadvantages, but suppose we encounter the following situation:
type User = {
username: string;
gender?: "male" | "female";
age?: number;
bio?: string;
password?: string;
};
const users: User = [
{
username: "awesomeuser",
},
{
username: "baduser",
},
{
username: "gooduser",
},
];
For the convenience of access, I want to convert the users
variable into an object whose property name is users
array index and value is users
array element (ie User type). How to define such a type?
You can do this:
type UserSet = { [key: number]: User };
const userSet: UserSet = users.reduce(
(set, user, index) => ({ ...set, [index]: user }),
{} as UserSet
);
You can also do this:
type UserSet = Record<number, User>;
How to implement Record
?
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。