Author: a tuque warehouse: Github, Gitee Tuque community main station (first) : Tuque community blog: Digijin, Zhihu, MOC public number: Tuque community contact me: after paying attention to the public number can add Tuque sauce wechat oh original is not easy, ❤️ like + comment + collection ❤️ three, encourage the author to write a better tutorial.

Welcome to TypeScript’s Getting Started to Practice series on Type is Justice:

  • Type is Justice: TypeScript from Starter to Practice (Prologue)
  • Type is Justice: TypeScript from Inception to Practice (PART 1)
  • Type is Justice: TypeScript from Getting Started to Practice, PART II

origin

JavaScript has taken over every corner of the world. Almost everywhere you can access a web page, JavaScript is in operation. However, because of the dynamic, weakly typed, interpreted language nature of JavaScript, and the hidden call stack of errors, developers not only spend a lot of time debugging errors, It is also extremely difficult to understand the code written by your teammates when developing in teams. TypeScript, a superset of JavaScript, is a compiled language that provides support for the type system and the latest ES syntax, allowing us to enjoy writing code using the latest ES syntax. It can also avoid many potential syntax and semantic errors in the process of writing code. And the type system it provides makes it easy for us to understand the meaning of teammates’ code: input and output when writing code in a team collaboration, which greatly improves the efficiency of team collaboration in writing large business applications. In the modern JavaScript world, there are many large libraries that use TypeScript for refactoring, including the three main front-end frameworks: React, Vue, Angular, and the well-known component libraries ANTD and Material. In many companies, large business applications are developing and even rewriting existing applications in TypeScript. So if you want to write large business applications or libraries, or want to write more collaborative code, There are good reasons to learn about TypeScript! React TodoList This is the first TypeScript tutorial in a series of tutorials on TypeScript syntax by using the ANTD component library to get a taste of TypeScript’s React TodoList application. This allows you to learn the grammar and complete a working project at the same time.

The source code for this article is available on Github or Gitee. If you think it is well written, please give ❤️ a thumbs up and Github or Gitee a star ❤️

This tutorial is part of the React front End engineer’s learning path. Welcome to Star and encourage us to continue to create better tutorials

The code for

The whole genre we’re going to talk about is justice: The “getting started” TypeScript series is based on a hands-on project that will take us through the entire tutorial cycle, so we need a hands-on project that covers TypeScript syntax as thoroughly and as cleanly as possible. Since preparing project code isn’t the focus of this series of tutorials, if you’re interested in learning how to setup a TypeScript React development environment, check out our introductory tutorial:

** If you’re already familiar with how TypeScript builds React development environments, configures Ant Design libraries, etc., or aren’t interested, you can just clone the code we’ve prepared for you:

If you prefer the code cloud, you can run the following command to get the initial code:

git clone -b initial-code https://gitee.com/tuture/typescript-tea.git
cd typescript-tea && npm install && npm start
Copy the code

If you prefer Github, you can run the following command to get the initial code:

git clone -b initial-code [email protected]:tuture-dev/typescript-tea.git
cd typescript-tea && npm install && npm start
Copy the code

After cloning the initial code with the command above and running the project, you should see something like this:








TypeScript que

Official TS time ☕️, TS is a static programming language that is a superset of JavaScript. First let’s explain what a programming language is, and then we’ll introduce what TypeScript is.

What is the programming language?

So what is a programming language? Programming languages are formal languages used to define computer programs. It is a standardized communication technique used to give instructions to a computer. Taking JS as an example, a standard programming language generally consists of the following parts:

  • Data structure: For example, the original data types are String, number, and void, and the non-original data types are array, Object, and enum
  • Control structure: if/else, switch, while, for loop, etc
  • Organizational structure: functions, classes
  • Features: such as JS prototype chains
  • Common API: isNaN determines if it is not a number and toFixed rounds decimals
  • Running environment: such as JavaScript on the browser side and Node on the server side

The first five are also called language kernels, commonly known as ECMAScript 2015, or ES6; Finally, the runtime environment becomes JavaScript by combining BOM/DOM on the browser side and Node by combining some file/network operations on the server side.

What is TypeScript?

TS, as a superset of JavaScript, contains two classes of properties:

  • Features of the programming language on the JavaScript side allow us to perform various javascript-related operations: Variable declarations, writing if/else control flows, using loops to handle repetitive tasks, using functions to perform specific chunks of work, using classes to organize and reuse code and simulate real-world operations, and new features such as decorators, Iterators, generators, etc. In this article, we assume that you already know this and won’t go into too much detail.
  • Features unique to the TypeScript side: Type, which also has a set of programming language features, such as marking a variable as string, a function as three parameters, string/number/ Boolean, return type never, etc. These are basic types, and we can even program based on type. This article focuses on the use of type versioning control and organizational structure to complete the writing of advanced types, and then attach the types to the corresponding programming language features of JavaScript, and make JS static, so that we can find errors in the type at compile time.

Good, read here, compared to many readers have clear, in fact, TS nothing mysterious, mainly is to design a set of similar type of programming language language, then these types attached on the language of the original JavaScript, adding type to its limit its static, thus can be quickly found when writing a lot of potential problems, TypeScript helps us write code that is less error-prone and more team-friendly, which is why TypeScript is great for writing large business applications.

Type language data structures

Among them, TS data structure includes primitive type, non-primitive type, special type and advanced type. We will combine the definition of TS type side, as well as the attachment of JS to the actual combat to explain.

The original type

TS type definition

Like primitive data types in JS, TS corresponds to consistent type definitions, including the following eight:

  • number
  • string
  • boolean
  • null
  • undefined
  • void
  • symbol
  • bigint

Symbol has been introduced since ES6. Bigint is new to ES2020.

This is the primitive type of TS, and we mentioned earlier that TS is about attaching a type to JS and typing it, so let’s look at how the primitive type attaches to JS and typing it.

Attached to the actual combat on JS

TS uses the unique colon syntax to attach the type defined by its type side to JS. Let’s look at a few examples: write the Slogan of the graph community in JS language.

const tutureSlogan = 'Tuq Community, gathering wonderful free practical training';
Copy the code

We can confirm that the Slogan is of type string, so we attach the corresponding TS type to its variable definition as follows:

const tutureSlogan: string = 'Tuq Community, gathering wonderful free practical training';
Copy the code

We add a type definition to the original JS tutureSlogan variable, which is a string variable. By doing this, the original JS variable is statically typed, and no other type can be assigned to the tutureSlogan variable at initialization. For example, if we assign a literal of type number to tutureSlogan, we get an error:

const tutureSlogan: string = 5201314 Type '5201314' is not assignable to Type 'string'
Copy the code

This is the power of TS, when the team is coding with the data type specified in advance, it will enforce constraints on the subsequent writing and calling of these typed variables, just like in the above code, if tutureSlogan is assigned 5201314, it will give an error. You can be more restrained, right 😌, Put a limit on 5201314, with quotation marks around it ‘5201314’ problem solved, love can also be restraint 🤓.

For tutureSlogan, we have limited the string type, but for our assignment 5201314, This is a JS number literal. Why is it a Type? For example, the right side of the assignment, 5201314, will be inferred to 5201314, which is a special number type that belongs to the number type. Assignable to variables of type number. A subtype can be assigned to a parent type. The number 1 can be assigned to number. But because number and string collide, there is an error. The TS compiler sees the original JS statement as a type, such as the statement above, in the eyes of the TS compiler. This is a comparison between type 5201314 and type string. If the comparison is consistent, then the TS compiler will let you off the hook today.

summary

There are eight primitive TS types, and we use string to explain how to attach TS to the original JS syntax to static JS language. The remaining seven primitive TS types are used in a similar way to string. We’ll use these types as we go along.

Nonprimitive type

TS type definition

Like non-primitive data types in JS, non-primitive data types also exist in TS, representing eight types other than the original type. Non-primitive data types are also called object types. In fact, there are several common non-primitive types in TS, as follows:

  • array
  • tuple
  • enum

And because they are object types, object types actually represent non-primitive types. In the above three types and their parent type object, array and object should be familiar, as for tuple and enum are new types in TS, the formal proposal is not currently in JS. Having covered type-side definitions, let’s move on to the array and enum non-primitive types above.

Array type attachment combat

We are familiar with the array type, but there is a difference here. Because it is a dynamic language, an array can have a variety of different data type items, for example, we see the following JS statement:

const arr = ['1'.2.'3'];
Copy the code

As you can see, if you look at the array variable arr from TS’s point of view, there are strings of type ‘1’ and ‘3’, and numbers of type 2. For example, we should declare the type of the array variable arr as follows:

const arr: string[] = ['1'.'2'.'3'];
Copy the code

As you can see, we declared the variable arr to be a string[], that is, a string[] followed by an array flag to indicate that it is an array of strings. Once we declared the string[], we needed to change the array 2 to the string ‘2’. We notice the array type, which requires that each item in the array be of the same type. This applies when the length of the array is unknown, and each item in the array is bound by a specific type, such as string. However, most students from JS may not be used to the array type, our JS students often encounter an array, where the number of items are of different types, just like our above JS arr items, both string and number type. So what’s going to happen? Also good! The designers of TS have this in mind for us, and that’s the tuple type we’ll talk about next.

Tuple type attachment combat

Tuple is a special type of array. It is used in cases where the number of items in an array is known and the type of each item is known.

const arr = ['1'.2.'3'];
Copy the code

We know that the first and third items in the above array are of type string, and the second item is of type number. Now we need to attach a type to this arr to make it static. This condition satisfies the application scenario of the tuple mentioned above. We can keep the above notation unchanged by giving ARR a corresponding tuple type:

const arr: [string.number.string] = ['1'.2.'3'];
Copy the code

As you can see, tuples are of the form type1, type2, type3,…., typen where the length of the array is known and the type is known, and all types from type1 to typen can be different.

summary

There are four non-primitive types in TS, one of which represents the non-primitive type Object, and the other three are object types. We then went through the array and tuple types in practice. We’ll leave the enum and object types themselves for a later chapter, but stay tuned to ✌️.

Special type

There are several other special types that are commonly used in TS, including any, unknown, and never. The never type is usually used with the function type declaration, so we will mention how to declare the function type when we use the never type. Now let’s talk about the meaning and application of these three types.

Any type definition and field

The literal meaning of any is “any”, which is used when you do not know the type of a variable, so you add an any definition to it to indicate that it can be any type, usually waiting until you confirm the type of the variable before changing any to the specific type. For example, we have the following TS variable definition statement:

let demand: any;
Copy the code

Because sometimes the products to a requirement, for us to develop a new function, gives the design draft, but I didn’t handover clear, there are some content for design draft we want to do in advance, but because of the type of not clear, such as the demand here, so we are here to demand an any type, and then continue to do other content, This will not make mistakes and will not affect the rest of the development schedule. Wait for the product to explain the specific context, ah! Now that we know the type of demand, we can go back and apply a strict type definition to it. For example, if we know that demand is of type string, we can go back and modify it as follows:

let demand: string;
Copy the code

That’s it. This is how any is used most of the time. Use AnyScript instead of AnyScript, which is the same as JS 😉. So you see, the beauty of TS is that you can write JS in A TS environment and enjoy the advantages of static languages that TS brings, so its popularity is understandable.

Unknown Type definition and combat

The unknown type and any can represent any type, and the application scenario is similar to the above type, but it is more secure. So where is the security? Let’s take a look at an example:

let demandOne: any;
let demandTwo: unknown;
Copy the code

When we get the development requirements, but do not know the specific type and plan to continue development, the above two cases can be used. However, when we use these two variables in detail, variables of any type can be arbitrarily assigned, instantiated, and executed by functions, while unknown only allows assignment. Instantiation, function execution, and so on are not allowed. Let’s look at an example:

demandOne = 'Hello, Tuture'; / / can
demandTwo = 'Hello, Ant Design'; / / can

demandOne.foo.bar() / / can
demandTwo.foo.bar() / / an error
Copy the code

As you can see, the unknown type only allows assignment, but not getters, function execution, etc., so it is more secure.

Never/function type definition and practice

Never literally means “never”, representative does not exist in the TS value type, commonly used in type declarations to the function, the function is never used when the return value, such as throwing an error in a function, we first look at an example to explain how to function type declaration, then we never type how to use:

function responseError(message) {
  / /... Specific operations, receive information, throw errors
}
Copy the code

For the above function, we can use the arrow function form to abstract it into something like (args1, args2… Argsn) => returnValue (argsn) => returnValue (argsn) => returnValue (argsn) => returnValue (argsn); The function has a single argument: message, and the body of the function throws the corresponding error based on message.

function responseError(message: string) :never {
  / /... Specific operations, receive information, throw errors
}
Copy the code

Since message is usually a string ID, we give it a string type. This function never returns a value. It simply throws an error, so we give the return value a never type.

Hands-on practice

Now that we have a basic understanding of the data structures of the type language, let’s write a little React code to put what we’ve learned into practice. In the code we prepared before, we can see that there are two fake data arrays todoListData and userList. We use the knowledge we learned before to type these two arrays. Open SRC/app. TSX and modify the corresponding contents as follows:

/ /... interface Todo { user: string; time: string; content: string; isCompleted: boolean; } interface User { id: string; name: string; avatar: string; } const todoListData: Todo[] = [{content: "mRcfps", user: "mRcfps", time: "March 2, 2020 19:34", isCompleted: false }, // ... ] ; const userList: User[] = [ // ... ] ; / /...Copy the code

TodoListData = Todo[]; todoListData = Todo[]; todoListData = Todo[]; UserList is of type User. Interface, which we haven’t talked about yet, but we’ll talk about in a second, is kind of like an object in JS, which organizes a set of types, like a single element in todoList is actually an object with four attributes, the first three of which are strings primitive, The last attribute is of Boolean type, so we use interface to type annotations for individual object elements.

Enumerations and interfaces

In the last video, we talked about interface, but we didn’t go into detail, so in this video we’re going to talk a little bit about what interface is.

Interface

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.

Let’s look at an example of what an Interface looks like in a second, like our previous object Todo. A Todo object looks like this:

const todo = {
  content: 'Tufinch Community, gathering wonderful free technical tutorials';
  user: 'mRcfps'.time: '2 March 2020 19:34'.isCompleted: false,}Copy the code

Now we want the todo to make a type annotation. We can define an Interface to annotate the todo 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

For example, if the content is String, the Interface looks exactly like the Todo object. Therefore, it is possible to annotate Todo with Interface Todo. Those of you who use VSCode should see that when we do this, there’s no exception thrown in the editor.

Optional attribute

Interface is used to annotate objects, functions, etc., so we have a scenario where we may not have some parameters in an object, such as a Todo, and sometimes the time attribute is not set. What should we do to modify such an object? Let’s look at the optional attribute. If time was optional in our example, we could write:

interface Todo {
  content: string;
  user: string; time? :string;
  isCompleted: boolean;
}
Copy the code

We see, only need to modify the colon attribute types on the left to add a question mark is ok, this time we will tell TS compiler this time a type attribute is optional, so we use the above Interface Todo annotation about no time attribute Todo object is as follows:

const todo: Todo = {
  content: 'Force content creation, speed up technology dissemination',
  user: 'pftom',
  isCompleted: false,}Copy the code

As you can see, those of you using VSCode to follow the tutorial should find that there are no errors and the type check passes.

Read-only property

The TS Interface has some additional attributes such as readonly, which means that when a JS element is annotated as a read-only attribute by an Interface with a read-only attribute, we cannot modify this attribute later.

interface Todo {
  content: string;
  readonly user: string; time? :string;
  isCompleted: boolean;
}
Copy the code

If you add the readonly keyword to the property, you can mark the property as read. Let’s test this effect:

const todo: Todo = {
  content: 'Force content creation, speed up technology dissemination',
  user: 'pftom',
  isCompleted: false,
}

todo.user = 'mRcfps'
Copy the code

When we make the above changes, the editor will report an error:


Redundant attribute check

I often encounter an object in JS. At the beginning, we know which attribute it has, but its attributes can be dynamically increased. For example, our todo may have a priority priority attribute. If you want to check for redundant properties, you can check for redundant properties.

interface Todo {
  isCompleted: boolean;
  [propName: string] :any;
}
Copy the code

We annotate that the Todo interface must have an isCompleted attribute. Other attributes can be added dynamically. Since the value type of the dynamically added attribute is unknown, we use any to indicate the value type. It can be of any type. Let’s try it out:

const todo: Todo = {
  content: 'Force content creation, speed up technology dissemination',
  isCompleted: false,
}

todo.user = 'pftom';
todo.time = '2020-04-04';
Copy the code

As you can see, our todo was defined with only two attributes. Later we added two additional attributes, and found that there is no error in the editor. This is the charm of redundant attribute checking.

Enum

Enumeration is a unique concept in TS, not in JS. It is mainly used to help define a series of named constants. It is often used to type annotations for a class of variables whose value is one of a set of values. This item belongs to one of the five users. Let’s look at an example in a moment where we put the five users into an enumeration:

enum UserId {
  tuture,
  mRcfps,
  crxk,
  pftom,
  holy
}
Copy the code

Further, we can improve the Todo Interface we saw in Interface to give its user field a more precise type annotation:

interface Todo {
  content: string;
  user: UserId;
  time: string;
  isCompleted: boolean;
}
Copy the code

As we can see from the above example, the user field in todo should be one of the five people. It could be tuture or mRcfps, we don’t know, so we write an enumerated UserId and use it to annotate the User field in Todo.

Digital enumeration

For example, userid. tuture has the value 0, userid. mRcfps has the value 1, and so on. The following enumerations are the values 2, 3, and 4, respectively. We can also assign a number to one of the enumerated values manually, so that the enumeration values are incremented by the assigned number. Let’s look at an example:

enum UserId {
  tuture,
  mRcfps = 6,
  crxk,
  pftom,
  holy,
}
Copy the code

The numbers for each of our enumerated values above are, in order: 0, 6, 7, 8, 9

String enumeration

Enumeration values can be strings as well as numbers, such as:

enum UserId {
  tuture = '66666666',
  mRcfps = '23410977',
  crxk = '25455350',
  pftom = '23410976',
  holy = '58352313',}Copy the code

As you can see, we assign each enumeration value to the corresponding string.

Heterogeneous enumeration

Of course an enumeration can have both string values and numbers:

enum UserId {
  tuture = '66666666',
  mRcfps = 6,}Copy the code

Hands-on practice

After learning about Interface and Enum, we immediately applied them to our projects to improve our to-do list application. Our SRC/app.tsx became more and more complex as we wrote more and more, so we decided to split the TodoInput component into a separate page, create a new todoInput.tsx in the SRC directory, and write something like this:

import React, { useState } from "react"; import { Input, Select, DatePicker } from "antd"; import { Moment } from "moment"; import { userList } from "./utils/data"; const { Option } = Select; enum UserId { tuture = "666666666", mRcfps = "23410977", crxk = "25455350", pftom = "23410976", holy = "58352313" } export interface TodoValue { content? : string; user? : UserId; date? : string; } interface TodoInputProps { value? : TodoValue; onChange? : (value: TodoValue) => void; } const TodoInput = ({ value = {}, onChange }: TodoInputProps) => { const [content, setContent] = useState(""); const [user, setUser] = useState(UserId.tuture); const [date, setDate] = useState(""); const triggerChange = (changedValue: TodoValue) => { if (onChange) { onChange({ content, user, date, ... value, ... changedValue }); }}; const onContentChange = (e: any) => { if (! ("content" in value)) { setContent(e.target.value); } triggerChange({ content: e.target.value }); }; const onUserChange = (selectValue: UserId) => { if (! ("user" in value)) { setUser(selectValue); } triggerChange({ user: selectValue }); }; const onDateOk = (date: Moment) => { if (! ("date" in value)) { setDate(date.format("YYYY-MM-DD HH:mm")); } triggerChange({ date: date.format("YYYY-MM-DD HH:mm") }); }; Return (< div className = "todoInput" > < Input type = "text" placeholder = "Input backlog content" value = {value. The content | | content} onChange={onContentChange} /> <Select style={{ width: 80 }} size="small" defaultValue={UserId.tuture} value={user} onChange={onUserChange} > {userList.map(user => ( <Option value={user.id}>{user.name}</Option> ))} </Select> <DatePicker showTime size="small" onOk={onDateOk} style={{ marginLeft: "16px", marginRight: "16px" }} /> </div> ); }; export default TodoInput;Copy the code

You can see the above content, mainly with the following parts of the modification:

  • We defined a new oneInterfaceTodoInputPropsIt is mainly used as a commentaryTodoInputOf this functional componentpropsType, you can see that this interface has two main fields, one isvalue, it isTodoValueType, one moreonChange, which is a function type indicating that the parent component will pass oneonChangeFunction, and we’ll talk about how TS annotates functions later.
  • Then we added an enumerationUserId, to summarize the five user ids of our application, and assign the corresponding values to the five enumerated constants artificially.
  • And then we improved and defined a new oneTodoValueInterface, which has three fields and is mainly used for flagsTodoInputPropsValues that may be passed down from the upper-middle component, so all three fields are optional
  • Finally, we define three responsesInputSelectDatePickerThe function,onContentChangeonUserChangeonDateOkIs used when the upper-layer component does not pass the corresponding attributesetXXXTo update the React state, otherwise triggertriggerChange, which is passed down by the parent componentonChangeMethod to update the corresponding state

We import the userList from./utils/data, and import the Moment to annotate the date of type Moment. We will create the./utils/data file and install the Moment as soon as possible.

In SRC/todoinput. TSX we import the Moment to annotate the onDateOk function parameter date, next we install it:

npm install moment
Copy the code
/ /... "Customize - cra" : "^ 0.9.1", "less" : "^ 3.11.1", "less - loader" : "^ 5.0.0", "" :" ^ 2.24.0 ", "react" : "^ 16.13.0 react - app -", "rewired" : "^ 2.1.5", "the react - dom" : "^ 16.13.0", / /...Copy the code

SRC /utils/data.ts; SRC/app.tsx; SRC /utils/data.ts;

interface Todo {
  user: string;
  time: string;
  content: string;
  isCompleted: boolean;
}

interface User {
  id: string;
  name: string;
  avatar: string;
}

export const todoListData: Todo[] = [
  {
    content: "Tuq Community: A Great Free Tutorial.",
    user: "mRcfps",
    time: "19:34 on 2 March 2020",
    isCompleted: false
  },
  {
    content: "Tuq Community: A Great Free Tutorial.",
    user: "pftom",
    time: "19:34 on 2 March 2020",
    isCompleted: false
  },
  {
    content: "Tuq Community: A Great Free Tutorial.",
    user: "Holy",
    time: "19:34 on 2 March 2020",
    isCompleted: false
  },
  {
    content: "Tuq Community: A Great Free Tutorial.",
    user: "crxk",
    time: "19:34 on 2 March 2020",
    isCompleted: false
  },
  {
    content: "Tuq Community: A Great Free Tutorial.",
    user: "Pony",
    time: "19:34 on 2 March 2020",
    isCompleted: false}];export const userList: User[] = [
  {
    id: "666666666",
    name: "The Tooquine Community",
    avatar: "https://avatars0.githubusercontent.com/u/39240800?s=60&v=4"
  },
  {
    id: "23410977",
    name: "mRcfps",
    avatar: "https://avatars0.githubusercontent.com/u/23410977?s=96&v=4"
  },
  {
    id: "25455350",
    name: "crxk",
    avatar: "https://avatars1.githubusercontent.com/u/25455350?s=96&v=4"
  },
  {
    id: "23410976",
    name: "pftom",
    avatar: "https://avatars0.githubusercontent.com/u/23410977?s=96&v=4"
  },
  {
    id: "58352313",
    name: "holy",
    avatar: "https://avatars0.githubusercontent.com/u/58352313?s=96&v=4"}];Copy the code

After splitting the TodoInput and moving the fake data into a separate file, we need to modify the corresponding parts of SRC/app.tsx as follows:

import React, { useRef } from "react";

/ /... In the middle as

import TodoInput from "./TodoInput";

/ /... In the middle as

import { todoListData } from "./utils/data";

const { Title } = Typography;
const { TabPane } = Tabs;

// Same in the middle

/ /... Delete the TodoInput section

/ /... TodoList stays the same

function App() {
  const callback = (a)= > {};

  const onFinish = (values: any) = > {
    console.log("Received values from form: ", values);
  };
  const ref = useRef(null);

  return (
    <div className="App" ref={ref}>/ /... In the middle as<Form.Item name="todo">
            <TodoInput />
          </Form.Item>
          <Form.Item>
            <Button type="primary" htmlType="submit">submit</Button>
          </Form.Item>
        </Form>
      </div>/ /... In the middle as</div>
	);
}

export default App;
Copy the code

As you can see, the main changes above are as follows:

  • We deleted the corresponding fake datauserListtodoListDataAnd its Interface definitionTodoUserAnd turn from what we createsrc/utils/data.tsIn the importtodoListData
  • And then we delete itTodoInputComponent, and import the one we created earlierTodoInputcomponent
  • And then we giveFormA submit button has been added to the forms section, as well as an extensiononFinishfunction
  • Finally, we removed some guides that were no longer needed

summary

In this section, we learned Interface (Interface) and enumeration (Enum). Interface is mainly used to annotate objects and other multi-attribute elements. Enumeration is a unique concept in TS, not in JS, mainly used to help define a series of named constants, often used to annotate a class of variables. Their values are one of a set of values, and we finally put these two concepts into practice by improving existing Todo applications.

Want to learn more exciting practical skills tutorial? Come and visit the Tooquine community.

The source code for this article is available on Github or Gitee. If you think it is well written, please give Github or Gitee a thumbs up at ❤️ or ❤️