TS – a Pick
Topic link
Implement the built-in Pick
for TS, but do not use it.
Select attribute K from type T to construct a new type.
Such as:
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'Clean room'.completed: false,}Copy the code
I. Key word description
Type: indicates type protection
The function of type is to give a type a new name (alias). It supports primitive types, union types, progenitors, and any other handwritten type you need. It is often used for union types, like interfaces, to describe the type of an object or function
Typeof is the typeof js, ts will automatically infer the type from the typeof your code:
// This is how type is usually defined
type PersonType = {
name: string
age: number
}
let people = {
name: 'people'.age: 20,}// Typeof can be defined by an ordinary object as type A and then used to constrain other variables
type PersonType1 = typeof people
let p1: PersonType = {
name: 'man'.age: 12,}Copy the code
pick
Pick in TS source code implementation:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Copy the code
What it does is extract all the K from T and generate a new type. The User type defined in the following example contains two mandatory attributes including puberty and age. So, if you specify people as User, you must include both attributes, or you will get a type-checking error:
interface User {
stature: number
age: number
}
const people: User = {
stature: 186.age: 20,}Copy the code
However, if I want people to contain only User type of stature attributes, I can do this with Pick. It tells TS to only extract the stature attributes from User.
// Success, the new types generated with Pick do contain only typical attributes
const people: Pick<User, 'stature'> = {
stature: 185,}// error, the new type generated with Pick does not contain the age attribute
const people: Pick<User, 'stature'> = {
age: 17,}Copy the code
PS :Pick is to extract a single attribute from all attributes of the type.
interface
Interface official link
It is equivalent to the JS object in the type, used to check the structure type of functions, classes, etc. The so-called structure type check, that is, the structure of two types is the same, then their types are compatible, which is also known as “duck type” in the world of computer science.
Cue what duck type? When a bird is seen walking like a duck, swimming like a duck, and quacking like a duck, it can be called a duck.
Now we want the todo object to make a type annotation. We can define an Interface to annotate it in the manner of the “duck type” mentioned earlier:
interface Todo {
content: string;
user: string;
time: string;
isCompleted: boolean;
}
const todo: Todo = {
// ...
}
Copy the code
The type generated interface
interface IPerson { name: string age: number like: Array < string >} interface IPickedPerson extends Pick < IPerson, 'name' | 'like' > {} / const p/generate a new interface: IPickedPerson = { name: 'zs', like: ['a', 'b'] }Copy the code
2. Use of pick
Scenario: Take a combination of several desired types from a composite type.
// Primitive type
interface TState {
name: string;
age: number;
like: string[];
}
// If you want only name and age, you can define one more
interface TSingleState {
name: string;
age: number;
}
// The disadvantage is that when Tstate changes, TSingleState does not change with it, so Pick should be used instead
interface TSingleState extends Pick<TState, "name" | "age"> {};
Copy the code
Generally we use extends for inheritance, but what about writing in generics? Generics constrain official documents
In the previous example, we sometimes wanted to manipulate a set of values of a certain type, and we knew what properties that set of values had. In the demo example, we tried to access the length property of value, but the compiler could not prove that every type has the length property, so we reported an error.
function demo<T> (value: T) :T {
console.log(value.length); // Error: T doesn't have .length
return value;
}
Copy the code
Instead of operating on all types of any, we want to restrict the function to any type with a.length attribute. As long as the type passed in has this attribute, we allow, that is, at least include this attribute. To do this, we need to list the constraints on T.
To do this, we define an interface to describe the constraints. Create an interface that contains the.length attribute and use this interface and the extends keyword to implement the constraint:
interface Lengthwise {
length: number;
}
function demo<T extends Lengthwise> (value: T) :T {
console.log(value.length); // Now we know it has a .length property, so no more error
return value;
}
// Now the generic function is constrained, so it no longer applies to any type:
demo(3); // Error, number doesn't have a .length property
// We need to pass in a value that matches the constraint type, which must contain the required attributes:
demo({length: 10.value: 3});
Copy the code
Third, antithesis
interface Todo {
title: string
description: string
completed: boolean
}
// Retrieve a series of K attributes from T
type MyPick<T, K extends keyof T> = { [S in K]: T[S] }
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'Clean room'.completed: false,}Copy the code
Extends is used in generics not to inherit, but to constrain types. So the K extends keyof T, which means that the key is bound to the keyof T.