preface
TypeScript is not new to people on the front end or even to people in the back end. Today we are going to talk about TypeScript, its basic usage, and how it is used in projects. By the way, TS is too big, because its types can be flexibly combined, but rest assured, this paper will not involve too many conceptual things (also can not finish), because in fact, in a big project, it is usually these basic types, such as type and interface, but also by position. If you’re the project leader or the head of the front end of your company and you’re really demanding or you’re writing tools, encapsulating common components, there’s a lot more opportunity to use those special things
In TS, it is best to specify the type as much as possible, because it is used to regulate their own team, if you use any, it is better to use js, if you only have your own project, then there is no need to use this stuff, and make trouble for yourself
The base type
Nerver, void, number, number, number, number, number, number, number, number, number, string, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number So let’s just do a quick list here
Basic types: number/string, Boolean/Array/object
Any null, undefined void never
tool
Since we need to compile TSC files every time we do experiments, and node files are too troublesome, I simply wrote gulp(not webpack because gulp is easier and faster), you can use it directly
In the comments section, someone pointed out that tSC-w can be directly compiled, which is actually the same, but I mainly want to make it easier for me to clear the screen when I watch, as well as all other file operations, so gulp is more convenient. I will leave a shelf here. If you are interested, you can find more convenient commands in the comments section or gulp official website
Usage:
cnpm i -g gulp-cli
– Install gulp itselfcnpm i
– Install local dependent librariesgulp watch
– Run the watch task of gulp
package.json
{
"name": "test"."version": "1.0.0"."main": "index.js"."license": "MIT"."dependencies": {
"gulp": "^ 4.0.2." "."gulp-clean": "^ 0.4.0"."gulp-run": "^ 1.7.1." "."gulp-typescript": 1 "" ^ 6.0.0 - alpha.."gulp-watch": "^ 5.0.1." "."typescript": "^ 3.7.4." "}}Copy the code
gulpfile.js
const gulp = require('gulp'),
watch = require('gulp-watch'),
ts = require('gulp-typescript'),
run = require('gulp-run'),
clean = require('gulp-clean');
gulp.task('watch', () = > {return watch('./1.ts', () => {
gulp
.src('./1.ts')
.pipe(
ts({
target: 'ES6'.outFile: '1.js'.experimentalDecorators: true,
}),
)
.on('error', err => {
// console.error(err);
})
.pipe(gulp.dest('build'))
.pipe(run('node build/1.js'));
});
});
Copy the code
The project structure is as follows
The results
Instead of creating the build manually, run gulp directly and it will be created and run automatically
An array of
Arrays have a lot of tricks, but here’s how to use them, and then we’ll talk about how to work with other things
let arr = Array<number>; // Specifies only an array of numbers
// let arr = number[];
Copy the code
Type – Interface
I am often asked what is the difference between TS type and interface. First of all, I must be sure that there are similarities and differences between these two functions, otherwise the author would not be wrong to make two out. Here we first say the use of respectively, and then the difference
Let’s assume that these are both custom types
First of all, the TS convention type can be specified inside json, which you all know is going to be like this and this is going to be an error
Strictly abide by it
type
But if you have a type that you’re going to use a lot, like a user type, and you’re going to have a name and an age, you’re not going to write a bunch of them every time you define a variable
So you can use it in multiple places
interface
The above example would be the same if you changed it to interface
The difference between
In fact, if you look at this example, you might think, well, it’s not the same, what’s the difference
interface
It needs to be implemented
Imagine that I have a requirement, and I have a class that encapsulates HTTP requests, and I can send the data directly to the server as a string and then I can get it back and parse it into JSON, but before I do that, let’s talk about another thing
implements
Implements is a bit like extends, which extends from a class. Instead of inheriting a class, implements an interface
So let’s do an example with interface
interface serializeable {
tostring(): string;
fromString(str: string) :void;
}
class SendData implements serializeable {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public tostring() {
return JSON.stringify({
name: this.name,
age: this.age,
});
}
public fromString(str: string) {
let data = JSON.parse(str);
this.name = data.name;
this.age = data.age; }}Copy the code
By the way, implements implements multiple interfaces at once, just by name, like this
interface serializeable {
tostring(): string;
fromString(str: string) :void;
}
interface serializeable2 {
}
class SendData implements serializeable, serializeable2 {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public tostring() {
return JSON.stringify({
name: this.name,
age: this.age,
});
}
public fromString(str: string) {
let data = JSON.parse(str);
this.name = data.name;
this.age = data.age; }}Copy the code
See this… I’m sure some people still have questions. So… How exactly does this thing work
Let’s try this with reference to the HTTP requirements we mentioned above, assuming that the data to be sent to the server now has to implement my interface
interface serializeable {
tostring(): string;
fromString(str: string) :void;
}
class SendData implements serializeable {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public tostring() {
return JSON.stringify({
name: this.name,
age: this.age,
});
}
public fromString(str: string) {
let data = JSON.parse(str);
this.name = data.name;
this.age = data.age; }}function sendToServer(obj: serializeable) {}
sendToServer(new SendData('name'.18));
Copy the code
There’s nothing wrong with looking at the console at this point
But let’s just arbitrarily switch classes
SendData2 didn’t implement my interface, so it just exploded. How does that help? Note that ⚠️ is useful for error detection. Normally, if you write in JS, you need to execute obj. Tostring in sendToServer or any other method of this interface to save the file. This will become a runtime error. So it’s nice that this thing just avoids some of the mistakes, right?
The generic
Generics are a little bit more special, so let’s look at an example, just to give you a sense of what this is all about. So I’m going to write a function, regardless of practicality, which is a function that passes in a number, the number of cycles, and returns an array of numbers
function repeat(item: number, count: number) :number[] {
let result: number[] = [];
for (let i = 0; i < count; i++) {
result.push(item);
}
return result;
}
let arr: number[] = repeat(13.4);
console.log(arr);
Copy the code
First things will come out, but… Repeat, now we only implement loop numbers, is it possible that in the future we will need to loop strings, booleans, and how much do we need to write them one by one so we have to find a way to pass the type, of course any can also be used, but… So if you use any in the introduction that I wrote you can just use JS and of course, this is just generics, but you can use any here as well
function repeat<T> (item: T, count: number) :T[] {
let result: T[] = [];
for (let i = 0; i < count; i++) {
result.push(item);
}
return result;
}
let arr: number[] = repeat<number> (13.4);
console.log(arr);
let arr2: string[] = repeat<string> ('aaa'.4);
console.log(arr2);
Copy the code
Is it easy?
In fact, if this looks familiar to you, yes, in TS an Array is a generic, like Array
and just to introduce another concept
Type conjecture
This is just our example, in fact, directly do not pass type, but also can come out
Ts are very smart, he can, depending on the type of you coming to speculate what type you are, of course, the Jane Jane, a little more complicated, such as a generic class, declared within an array, then the add method, for the first time is digital, the second is the string that he couldn’t speculate, too much not sure. Actually this generic speaking, is very huge, this if you are interested can leave a message or comment on a single chapter dedicated open it, because there are some variants of this generic, for example, there are more than two generics, three, respectively, in where, and can also have optional type, replace type, the type of joint, cross type, There’s a lot of weird stuff out there, so… If you are interested, please leave a message
A decorator
The decorator actually it is like to use my personal, he can directly give class to add some functionality Actually there is someone there may be a doubt, why do I want to use this thing, I directly add not just finished yao, also save trouble, actually can imagine, now need to use the user data is attached to this class, I must first point, It is possible to add one by one, but it is trouble. As the saying goes, laziness is the greatest power to advance human progress. In fact, if you know about Vue 2.x TS, you should know that it is full of decorators. (By the way, the message released by VUe3 is that the decorator is discarded, probably because it is an experimental feature for the time being, the details need to be informed later.)
How to write a simple decorator
Class decorator
The decorator is just a function, and you just add an @ sign to the class, and you have to pay attention to the arguments, or ts will give you an error
Note that ⚠️ fn only has one argument for class decorators, not for properties and methods, as discussed below
function fn(target){}@fn
class User {
}
Copy the code
By the way, if you’re using vscode or some other editor, it might give you an error, right
{
"compilerOptions": {
"target": "ES5"."experimentalDecorators": true}}Copy the code
If I write this, I won’t get an error
The target is actually the constructor of our class
function fn(target) {
console.log(target);
target.a = 12;
}
@fn
class User {}
console.log(User.a);
Copy the code
If you look at the result, you’ll see that an error has been reported and the result has been returned, which is very strange
In fact, ts is very strict, it must be used at initialization, runtime is fine, the results are fine, but I just can’t detect that… What to do? It’s easy, we can just define this property on our class, like this
function fn(target) {
console.log(target);
target.a = 12;
}
@fn
class User {
static a: number;
}
console.log(User.a);
Copy the code
If you run it again, no errors will be reported
Decorator parameter passing
The target (constructor) parameter is passed inside the function returned by the constructor function. The outermost layer is the parameter passed in
function fn(num:number) {
return function(constructor: Function){
constructor.prototype.a = num
}
}
@fn(12)
class User {
a: number;
}
let obj = new User();
console.log(obj.a);
Copy the code
See at run time
Now, let’s write two classes, and we can pass parameters to distinguish them
function fn(num:number) {
return function(constructor: Function){
constructor.prototype.a = num
}
}
@fn(12)
class User {
a: number;
}
let obj = new User();
console.log(obj.a);
@fn(5)
class User2 {
a: number;
}
let obj2 = new User2();
console.log(obj2.a);
Copy the code
Results:
That’s great, isn’t it
The advanced
In fact, decorators have been able to meet most people’s work needs up to the last step, because this thing
- It’s an experimental thing
- It’s rarely used at work
However, there are a few interesting things to share with you
Preface: We this class, certainly do not know an instance right, so next, let’s write so, a direct attribute a little trouble, but… What if it’s JSON? Let’s look at an example
Now that I’ve changed it to JSON, there’s nothing wrong with that. Now what
Prototype this way is not complete, so don’t use this decorative food pass to picture the project, it will kill people. But what to do… I don’t want to add it to anyone, so I can just say it’s the right thing to do, and I can just rewrite that class, but there’s a problem, and I can’t just copy the code and do it again, so I can just add the code
function fn(num: number) {
return function<T extends {new(... arg:any[]) : {}} > (constructor: T) {
return class extends constructor {
json: object = { a: num };
};
};
}
@fn(12)
class User {
json: {
a: number;
};
}
let obj = new User();
obj.json.a = 80;
console.log(obj.json);
let obj2 = new User();
console.log(obj2.json);
Copy the code
At this point, there is no problem ~ is not very simple of course… Put your knife down, and some of you might say, wait, wait, wait, wait, wait, wait, wait, wait, wait, wait, wait, wait. Arg :any[]):{}}>
Well, actually, let’s get rid of this and take a look
But direct write T also not line, just say, let’s the T to inherit an interface, and the interface is not a common interface, need is a dynamic interface, so you need to dynamically create a function Is the new code above () and, what is this parameter, so take out all the new (… Args :any[]) this extends {new(…).
Ok, that’s all for this ts tutorial. If you have any questions, please feel free to comment in the comments section. Or you can add my QQ and wechat to communicate with us.
916829411
Copy the code
WeChat:
Dyy916829411
Copy the code