TypeScript是微软开发的JavaScript的超集,遵循ES6。由于项目需要,博主自行学习了一下TypeScript基础知识,并分享给大家,有问题请随时评论区交流~
sudo npm install -g typescript
使用tsc命令的方式编译TypeScript文件
//创建TypeScript文件:TypeScriptTest.ts
export class Hello{}
tsc TypeScriptTest.ts
"use strict";
exports.__esModule = true;
var Hello = /** @class */ (function () {
function Hello() {
}
return Hello;
}());
exports.Hello = Hello;
使用WebStorm编译器可以设置直接编译TypeScript文件而不用手动编译
传统JavaScript使用多行字符串时需要用+
连接,不便于阅读
var str = "aaa" +
"bbb" +
"ccc";
TypeScript使用“包裹字符串可以直接实现多行效果
var str = `aaa
bbb
ccc`;
使用字符串模板,可以在字符串中直接加入对应字符串变量内容或函数调用结果,而不用再使用+
拼接
实例
var name = "Jack wangzhe";
var getName = function(){
return "Jack wangzhe";
}
console.log(`
Hello ${name}
Nice to meet you, ${getName()}
`);//使用字符串模板需要用``包裹,并在内部使用${}包裹对应变量或方法
var name = "Jack wangzhe";
var getName = function () {
return "Jack wangzhe";
};
console.log("\n\n Hello " + name + "\n Nice to meet you, " + getName() + "\n\n");
用字符串模板调用一个方法,同时把模板里的表达式传递给方法的参数
实例代码
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var name = "Jack wangzhe";
var getAge = function () {
return 20;
}
test`Hello my name is ${name}, and I am ${getAge()}`;//自动拆分字符串传递给方法参数时不加圆括号,直接写``及其内容
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var name = "Jack wangzhe";
var getAge = function () {
return 20;
};
test(__makeTemplateObject(["Hello my name is ", ", and I am ", ""], ["Hello my name is ", ", and I am ", ""]), name, getAge());
Array(3)
Jack wangzhe
20
在参数名称后面使用冒号来指定参数的类型【变量、方法和方法参数都适用】
(只会在TypeScript编辑器里进行提醒,但是编译成js不会报错,因为js是弱类型)
【TypeScript本身也有类型推断机制,在第一次为变量赋值时自动推断变量的类型,会在变量赋值类型变化时进行报错提醒。如果希望字符串被赋任何类型都不进行报错则给变量赋成any类型。】
//TypeScript代码
var name: string = "Jack wangzhe";
var alias: any = "xixi";
var age: number = 18;
var man: boolean = true;
function test(name: string): string{
return "";
}
//编译后的JavaScript代码
var name = "Jack wangzhe";
var alias = "xixi";
var age = 18;
var man = true;
function test(name) {
return "";
}
any:任意类型
string:字符串
number:数字类型
boolean:布尔类型
void(声明方法的返回值):不需要任何返回值
使用class或接口声明自定义类型
//eg.
class Person{
name:string;
age:number;
}
//使用时eg.
var zhangsan:Person = new Person();
zhangsan.name="zhangsan";
zhangsan.age=18;
在参数声明后面用等号来指定参数的默认值(注意:带默认值的参数要声明在参数的最后面)
//TypeScript代码
var name:string="Jack wangzhe";
function test(a: string, b: string, c: string = "Jack") {
console.log(a);
console.log(b);
console.log(c);
}
test("aaa", "bbb", "ccc");
test("aaa", "bbb");//由于c有默认值,故可传可不传
//JavaScript代码
var name = "Jack wangzhe";
function test(a, b, c) {
if (c === void 0) { c = "Jack"; }
console.log(a);
console.log(b);
console.log(c);
}
test("aaa", "bbb", "ccc");
test("aaa", "bbb");
在方法的参数声明后面用问号来标明此参数为可选参数(若没传则为undefined)
【可选参数必须声明在必选参数的后面】
//TypeScript代码
function test(a: string, b?: string, c: string = "Jack") {
console.log(a);
console.log(b);
console.log(c);
}
test("aaa");
//JavaScript代码
function test(a, b, c) {
if (c === void 0) { c = "Jack"; }
console.log(a);
console.log(b);
console.log(c);
}
test("aaa");
...
声明)//TypeScript
function func1(...args) {
args.forEach(function (arg) {
console.log(arg);
})
}
func1(1, 2, 3);
func1(7, 8, 9, 10, 11);
//JavaScript
function func1() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
args.forEach(function (arg) {
console.log(arg);
});
}
func1(1, 2, 3);
func1(7, 8, 9, 10, 11);
//TypeScript
function func1(a,b,c) {
console.log(a);
console.log(b);
console.log(c);
}
var args1 = [1, 2];
var args2 = [7, 8, 9, 10, 11];
func1(...args1);//会报错,最终输出1 2 undefined
func1(...args2);//会报错,最终输出7 8 9
//JavaScript
function func1(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args1 = [1, 2];
var args2 = [7, 8, 9, 10, 11];
func1.apply(void 0, args1);
func1.apply(void 0, args2);
//TypeScript代码
function* doSomeThing(){
console.log("start");
yield;
console.log("end");
}
var test = doSomeThing();
test.next();//输出start,停在yield
test.next();//输出end
//JavaScript代码
"use strict";
var _marked = /*#__PURE__*/regeneratorRuntime.mark(doSomeThing);
function doSomeThing() {
return regeneratorRuntime.wrap(function doSomeThing$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
console.log("start");
_context.next = 3;
return;
case 3:
console.log("end");
case 4:
case "end":
return _context.stop();
}
}
}, _marked, this);
}
var test = doSomeThing();
test.next();
test.next();
针对对象的析构表达式用{},针对数组的析构表达式用[]
对象属性名:新变量名
对变量进行赋值//利用析构表达式从对象中拆分属性
function getStock() {
return {
code: "CodeTest",
price: {
price1: 200,
price2:400
},
aaa: "aaa",
bbb: "bbb"
}
}
var { code: codex, price: { price2 } } = getStock();
console.log(codex);//CodeTest
console.log(price2);//400
//使用析构表达式从数组中拆分元素
var array1 = [1, 2, 3, 4];
var [num1, , num2] = array1;
console.log(num1);//1
console.log(num2);//3
var [num1, num2, ...others] = array1;
console.log(others);//[3,4]
function doSomeThing([num1, num2, ...others]) {
console.log(num1);//1
console.log(num2);//2
console.log(others);//[3,4,5]
}
doSomeThing([1, 2, 3, 4, 5]);
用来声明匿名函数,消除传统匿名函数的this指针问题
(参数)=>{函数体}
若参数为一个则()
可以省略直接写参数,若只有一个表达式则{}
可以省略直接写内容实例代码
function getStock1(name: string) {
this.name = name;
setInterval(function () {
console.log(`name is ${this.name}`);
}, 1000);
}
getStock1("Jack");//循环输出this is [目前最新测试已经修复此问题,会正常输出this is Jack]
function getStock2(name: string){
this.name = name;
setInterval(()=>{
console.log(`name is ${this.name}`);
}, 1000);
}
getStock2("Tom");//循环输出this is Tom
forEach()
只循环数组元素不循环到数组属性
for in
循环数组中元素下标和属性名
for of
循环数组中数组元素(不循环属性值),且可以使用break关键字停止循环
实例代码
var array = [1, 2, 3, 4];
array.name = "Jack";//在TypeScript中编译会报错,因为TypeScript不支持给数组添加属性的语法
array.forEach(val => console.log(val));//1 2 3 4
for (var key in array) {
console.log(key);//0 1 2 3 name
}
for (var val of array) {
console.log(val);//1 2 3 4
}
for (var val of array) {
if (val == 3) {
break;//1 2
}
console.log(val);
}
class Person{
name;
eat(){
console.log("I am eating");
}
}
var p1 = new Person();//类的实例化
p1.name = "batman";
p1.eat();
访问控制符
public
在类的内部和外部都能被访问到(默认)private
在类的内部才能访问到protected
在类的内部及类的子类能访问到类的构造方法
在类的实例化的时候被调用,且只被调用一次
方法名称constructor(参数)
当构造方法参数为public属性修饰时,会自动将该参数作为类的属性并赋值(如果没有加public则不将对应的参数声明为属性)
//eg.
class Person{
constructor(public name:string){
}
eat(){
console.log(this.name);
}
}
var p1 = new Person("batman");//执行的操作为将batman赋值给name,name作为Person的属性值存在
p1.eat();//batman
类的继承
extends
用来声明一种继承的关系。super
子类的构造函数必须要调用父类的构造函数
super(参数)
super.父类方法();super.父类属性;
//eg.
var workers:Array = [];
workers[0] = new Person("Jack");//成功,将Person对象放置workers中
workers[1] = new Employee("Tom","2");//成功,将Employee对象放置workers中(因为Employee是Person类的子类)
workers[2] = 2;//编译报错,不能放置非Person类型的元素
interface
声明。当接口作为方法参数的类型声明时,调用方法时,typescript会去检查传入的参数是否满足声明时接口中的所有属性。implements
实现接口,当一个类实现了某个接口,则必须实现该接口的所有方法。//声明接口
interface IPerson{
name:string;
age:number;
}
//声明类
class Person{
constructor(public config:IPerson){}
}
//调用
var p1 = new Person({
name:"zhangsan",
age:18
});//多传一个或少传一个属性都会报错,因为没有满足接口所声明的属性的要求
//声明动物接口
interface EatSomeThing{
eat();//接口中的方法没有方法体
}
//实现类
class Cat implements EatSomeThing{
eat(){//需要实现接口中的所有方法
console.log("I like eat Meat")
}
}
模块可以帮助开发者将代码分割为可重用的单元。开发者可以根据自己决定将模块中的哪些资源(类、方法、变量)暴露出去供外部使用,哪些资源只在模块内使用。[一个文件就是一个模块]
export
导出import
导入//a.ts
export var prop1;
var prop2;//没有对外暴露
export function func1(){
}
function func2(){
}//没有对外暴露
export class Clazz1{
}
class Clazz2{
}//没有对外暴露
//b.ts
import{prop1,func1,Clazz1} from './a';
console.log(prop1);
func1();
new Clazz1();
类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包(如:JQuery)
【这个文件其实就是一个TypeScript的模块,它把要使用的JavaScript要使用的工具包中的工具以TypeScript模块的形式暴露出来,从而使用】
先引入jquery的类型定义文件index.d.ts
【下载地址:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jquery/index.d.ts】
使用时直接使用对应jquery的方法即可
//eg.
export function func1(){
$("xxx").hide();
}
【https://github.com/DefinitelyTyped/DefinitelyTyped】
【https://github.com/typings/typings】