NPM 安装 TypeScript
npm install -g typescript
查看版本号
tsc -v
在vscode中配置ts自动生成js文件
- 在项目根目录
tsc --init
- 改 生成的
tsconfig.json "outDir": "./js"
(可以配置生成项目的路径) - 任务 -- 运行任务 -- 监视
tsconfig.json
ts 为了使编写的代码更规范,更有利于维护,增加了类型校验
写 ts 代码必须指定数据类型
基本数据类型
Boolean
var flag:boolean = true;
flag = false;
Number
var num:number = 123;
num = 456;
String
var str:string = 'str';
Array
demo1
在数字类型后面加 []
var arr:number[] = [1,2,3,4,5]; // 正确写法
var arr:number[] = ['a',1,2]; // 错误写法
demo2
使用数组泛型
var 数组名:Array<数组值类型> = [xx,xx,xx]
var arr:Array<number> = [1,2,3,4];
var arr:Array<string> = ['1','2','3','4'];
demo3
借助于 any 数据类型
var arr3:any[] = ['1',2,'test'];
demo4
元组类型 ==》tuple类型
属于数组的一种
var tup:[number,string] = [123,'this is tuple']; // 正确写法
var tup:[number,string] = [123,2,'this is tuple']; // 错误写法
元组类型 tuple
用来表示已知元素数量和类型的数组,各元素的类型不需要相同,对应位置的类型需要相同
let x: [string, number];
x = ['Runoob', 1]; // 运行正常
x = [1, 'Runoob']; // 报错
console.log(x[0]); // 输出 Runoob
枚举类型 enum
枚举类型用于定义数值集合
enum 枚举名 {
标识符[=整型常数],
标识符[=整型常数],
....
}
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c); // 输出 2
enum res {
success = 1,
error = 0
}
let res_flag:res = res.success;
console.log('枚举类型',res_flag); // 1
注意:如果标识符没有赋值,那么它的值就是该标识符的下标(没有赋值,会在前一个值的基础上递增)
any 任意数据类型
任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型,它常用于以下三种情况
var an_str:any = 'Test any type';
an_str = '0123';
Null 和 Undefined
null
在JS中 null 表示 “什么都没有”。
null 是一个只有一个值的特殊类型。表示一个空对象引用。
用 typeof 检测 null 返回的是 object
undefined
// 一个元素定义多个数据类型
var doc:number | undefined | null;
doc = 123;
void类型
typescript中的void表示没有任何数据类型,一般用于定义方法的时候没有返回值
function testVoid():void {
console.log('void类型');
}
// 函数有返回值,并且返回值是 数值类型
function testNum():number {
let num:number = 123;
return num;
}
函数的定义方式
函数声明法
function testFun():number {
let test_num:number = 123;
return test_num;
}
匿名函数法
let test_num2 = function():string {
let test_str:string = 'Test function';
return test_str;
}
console.log('111',test_num2());
函数传参
function testParams(name:string,age:number):string {
return `${name}-----${age}`;
}
console.log('函数传参',testParams('张三',20));
可选参数
注意:可选参数必须配置到参数的最后面
function chooseParams(name:string,age?:number):string {
return `${name}-----${age}`;
}
console.log('可选参数',chooseParams('zs'));
默认参数
function defaultParams(name:string,age:number=30):string {
return `${name}-----${age}`;
}
console.log('默认参数',defaultParams('zs'));
剩余参数
使用es6拓展运算符是为了保证参数个数不确定的情况
function surplusParams(a:number,...arr:number[]):number {
let sum = a;
for (var i = 0;i<arr.length;i++) {
sum += arr[i];
}
return sum;
}
console.log('剩余参数',surplusParams(10,1,2,3,4));
函数重载
定义:
函数名相同,参数个数,参数类型,参数顺序不同
意义:
传入不同的参数,得到不同的结果
function add (arg1: string, arg2: string): string
function add (arg1: number, arg2: number): number
// 需要使用 | 或 ? 操作符,把所有可能的输入类型全部包含进去
function add(arg1:string | number,arg2:string | number) {
if(typeof arg1 === 'string' && typeof arg2 === 'string') {
return arg1 + arg2;
} else if(typeof arg1 === 'number' && typeof arg2 === 'number') {
return arg1 + arg2;
}
}
alert(add('Hello','World'))
TS中定义类
class Person {
public name:string; // 属性
constructor(n:string) { // 实例化类的时候会触发
this.name = n;
}
run():void {
alert(this.name);
}
}
var p = new Person('张三');
p.run();
属性修饰符
/**
* public: 公有的, 在类内部,子类,类外面都可以访问
* protected: 保护类型 在类内部,子类 可以访问
* private:私有 在类内部,可以访问
*
* 属性如果不加任何修饰符,默认是 public
*/
继承
通过 extends 和 super 实现
class Student extends Person {
constructor(name:string) {
super(name); // super 在此处,就相当于 父类中的 constructor
}
}
var s = new Student('李四');
s.run();
多态
父类定义一个方法不去实现,让继承它的子类去实现,每一个子类都有不同的实现方式
class Anil {
name:string;
constructor(name:string) {
this.name = name;
}
eat() { // 具体怎么吃 父类 不去实现,让继承它的子类去实现,每个子类的实现方式都不同
console.log('吃的方法');
}
}
class Cat extends Anil {
constructor(name:string){
super(name);
}
eat() {
alert(`${this.name} 吃肉`);
}
}
var c = new Cat('小猫');
c.eat();
class Dog extends Anil {
constructor(name:string){
super(name);
}
eat() {
alert(`${this.name} 吃骨头`);
}
}
抽象类
抽象类用于提供其它类继承的基类,不能直接被实例化
使用 abstract 关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体的实现,必须 在派生类 中实现
主要作用:
抽象类和抽象方法主要是用来定义标准的,例如:Animation 这个类要求它的子类必须包含 eat 方法
abstract class Animaltion {
name:string;
constructor(name:string) {
this.name = name;
}
abstract eat():any; // 抽象方法
run() {
alert('抽象类中也可以有普通的方法');
}
}
/**
* 注意:抽象类的子类,必须实现抽象类中的抽象方法
*/
class Cat extends Animaltion {
constructor(name:string) {
super(name);
}
eat() {
alert(`${this.name}吃小鱼`);
}
}
var c = new Cat('小花猫');
c.eat();
c.run();
继承,多态,抽象类总结
相同点:
多态和抽象类 都是属于继承的一种
多态和抽象类不同点:
-
抽象类使用
abstract
关键字定义,多态不使用 -
抽象方法不包含具体的实现,没有方法体,而多态中的方法有方法体
-
eat() { // 具体怎么吃 父类 不去实现,让继承它的子类去实现,每个子类的实现方式都不同 console.log('吃的方法'); } abstract eat():any; // 抽象方法
-
-
抽象类中的抽象方法其子类必须去实现, 而 多态中的方法其子类可以去实现,也可以不去实现
-
抽象类中有 抽象方法 和普通方法,普通类中只能有 普通方法 ,不能有 抽象方法
接口
接口的作用
用于定义标准
在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范
在程序设计里面,接口起到一种限制和规范的作用。
接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里面方法的实现细节,它只规定这批类必须提供某些方法,提供这些方法的类,就可以满足实际需要。
ts中的接口类似于java,同时还增加了更加灵活的接口类型,它包括属性,函数,可索引和类等
属性类接口
interface FullName {
name:string;
age:number;
gender?:string; // 可选参数
}
function getInfo(info:FullName) {
console.log(`姓名:${info.name} -- 年龄:${info.age} -- 性别:${info.gender}`);
}
function showInfo(show:FullName) {
console.log(`姓名:${show.name} -- 年龄:${show.age} -- 性别:${show.gender}`);
}
/**
* 这种传递参数的方式:必须和接口中定义的参数保持一致,接口中未定义的参数,不能传递
*/
getInfo({
age:20,
name:'张三',
gender:'男'
})
showInfo({
name:'李四',
age:18
})
/**
* 这种传递参数的方式,只要对象中的参数 包含 接口中定义的参数就可以
*/
let obj = {
name:'张三',
age:20,
gender:'男',
hobby:'吃'
}
// getInfo(obj);
函数类型的接口
传入的参数,以及返回值进行约束
// 模拟加密的函数类型接口
interface encrypt {
(key:string,value:string):string;
}
/**
* md5:encrypt 这句化的意思是:md5引用 encrypt 这个函数
*/
/**
* 注意:function(key:string,value:string):string
* 函数的参数名可以是其它的 function(a:string,b:string)
* 但是参数名的数据类型,必须相同,且函数的返回类型也必须一致
*/
var md5:encrypt = function(key:string,value:string):string {
return key + value;
}
console.log(md5('aaa','bbb'));
可索引接口
主要用于对 数组 和 对象 进行处理 (不常用)
interface userInfo{
[index:number]:string; // [index:索引的类型]:数组中每一项类型的限制,当索引的类型为 number=》是数组,是string =》对象
}
/**
* 索引的数据类型为 number类型,数组中的每一项 为 string类型
*/
var arrInfo1:userInfo = ['1','2','3'];
interface objInfo{
[index:string]:number;
}
/**
* 索引的数据类型为 string,每一项的值为 number类型
*/
var objInfo1:objInfo = {name:1,age:2};
类类型接口
对类的约束,和抽象类类似
通过 interface,implements 关键字来实现
interface Anim{
name:string;
eat(str:string):void;
}
/**
* 一个类如果要实现某一接口,必须要与接口中的属性和方法一致
*/
class Catd implements Anim {
name:string;
constructor(name:string) {
this.name = name;
}
eat() {
console.log(`${this.name}吃肉`);
}
}
var catd = new Catd('小猫');
catd.eat();
可扩展接口
接口可以继承接口
interface Anim{
name:string;
eat(str:number):void;
}
interface Animations extends Anim {
work():void;
}
class Catd {
age:number;
constructor(age:number) {
this.age = age;
}
code() {
console.log(`写代码`);
}
}
class Progrems extends Catd implements Animations {
gender:number; // Progrems 私有的 gender 属性
name:string; // 实现接口 Anim 的name属性
constructor(gender:number,name:string) {
super(gender);
this.gender = gender;
this.name = name;
}
work() { // 实现接口 Animations 的方法
console.log(`work方法---${this.name}---gender${this.gender}`);
}
eat() { // 实现接口 Anim 的方法
console.log('eat方法');
}
}
var progrems = new Progrems(1,'张三');
progrems.work();
泛型
在软件工程中,我们不仅要创建一致的,定义良好的API,同时也要考虑可重用性。
组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型。这在创建大型系统时为你提供十分灵活的功能
在像 Java或 c#这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件
简单理解
泛型就是解决 类 接口 方法的复用性,以及对不特定数据类型的支持
更新中。。。。。