1、安装ts
npm install -g typescript
查看安装成功与否
tsc -V
2、初始化congfig.json
在init后config.json后打开“outer”:“./js”
tsc --init
3、编译ts文件
将xxx.ts编译成js
tsc xxx.ts
4、配置实时编译
vscode里面菜单\终端\运行任务\typescript\ts:监视
如果vscode报错,则参考下文
https://blog.csdn.net/qq_45164496/article/details/102170303
5、变量定义
定义变量需要指定数据类型,变成了强类型语言
var a:string=123;
var a: number = 123
console.log(a);
let str: string = 'hello world'
let str1:string="hello san"
console.log(str1);
//第一种数组写法
let arr: number[] = [2, 3, 45, 355]
console.log(arr);
//泛型写法
let arr1:Array<string>=["zhangsan","lisi","wanger"]
console.log(arr1);
6、元祖类型
//元祖类型属于数组的一种,多种数据类型的混装数组
let arr: [string, number, boolean] = ["zhangsan", 234, true]
console.log(arr);
7、枚举类型
//定义枚举类型
enum Flag { success = 1, error = -1 ,middle}
let f1 = Flag.success;
let f2 = Flag.middle
let f3:Flag=Flag.error
console.log(f1,f2,f3);
8、Any类型
let myvar: any = 'mystring'
console.log(myvar);
myvar = 1234;
console.log(myvar);
在dom操作里也可以使用any类型
const mybox:any = document.getElementById('mybox');
mybox.style.color = 'red';
9、null类型和undefined
一个元素可以设置多个类型
let num: string | undefined | null;
num='str'
console.log(num);
10、使用void定义无返回值的方法或者函数
function myfun(params:string): void {
console.log(params);
}
myfun('hello moto')
11、never类型
never类型是其他类型,包括null和undefined的子类型,代表从来不会出现的值
never变量只能被never类型所赋值
var a: never;
a = (() => {
throw new Error('错误')
})()
12、any类型的数组
let myarry: any = ['zhangsan', 14, 5, true]
console.log(myarry);
13、函数定义
//es5
function fun() {
}
var myfun2 = function () { }
//ts
function fun1(): string {
return 'mystr'
}
var myfun3 = function (): string {
return 'mystr'
}
var myfun4 = function (name: string, age: number): string {
//return name+' '+age//使用es的方法也是可以的
return `${name} ${age}`
}
let mystr = myfun4('zhagnsan', 34)
console.log(mystr);
var myfun5 = function (name: string, age: number): void {
let mystr = `${name} ${age}`;
console.log(mystr);
}
myfun5('lisi',34);
14、问号?方法的可选参数
es里面的方法形参和实参可以不一样,但ts中必须一致,如果不一致(数目)就需要配置可选参数
使用问号?表示问号后的参数可传可不传,可选参数必须放在参数列表最后
function myfun(name: string, age?: number) {
if (age) {
console.log(`${name} ${age}`);
} else {
console.log(name);
}
}
myfun('zhagnsan', 34)
myfun('lisi')
15、默认参数(参数的默认值)
es5不能设置默认参数
es6和ts可以设置默认参数,可以设置参数的默认值
function myfun(name: string, age: number = 18) {
console.log(`${name} ${age}`);
}
myfun('zhangsan', 35)
myfun('lisi')
16、三点运…算符表示剩余参数
实际是传了一个数组进去
function myfun(a: number, b: number, c: number, ...last: number[]) {
let result = a + b + c;
for (var i: number = 0; i < last.length; i++) {
result+=last[i]
}
console.log(result);
}
myfun(3,4,5,6,7,78,89)
17、函数重载
为同一个函数提供多个函数类型定义和java略有不同
function myfun(name: string):void;
function myfun(age: number):void;
function myfun(str: any): void { //最后这个函数的参数一定要是any,因为前连个函数的参数类型是不一定的
if (typeof str == 'string') {
console.log(`my name is ${str}`);
} else {
console.log(`my age is ${str}`);
}
}
myfun('zhangsan')
myfun(12)
重载也可以在参数的数目上有所不同
function myfun(name: string,age:number):void;
function myfun(age: number):void;
function myfun(str: any,age?:any): void { //最后这个函数的参数一定要是any,因为前连个函数的参数类型是不一定的
if (typeof str == 'string') {
console.log(`my name is ${str} ${age}`);
} else {
console.log(`my age is ${str}`);
}
}
myfun('zhangsan',14)
myfun(12)
18、箭头函数
同es6的箭头函数
19、定义类
较为接近java的类定义
class Person {
uname: string;
constructor(name:string) {
this.uname = name;
}
run():void {
console.log(`${this.uname} instance method`);
}
}
let p1 = new Person('zhangsan')
p1.run()
20、get,set
class Person {
uname: string;
constructor(name:string) {
this.uname = name;
}
getName(): string {
return this.uname;
}
setName(name: string) {
this.uname = name;
}
run():void {
console.log(`${this.uname} instance method`);
}
}
let p1 = new Person('zhangsan')
p1.setName('lisi')
p1.run()
21、extends,super类继承
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
run(): string {
return `${this.name} is moving`
}
walk():void {
console.log(`${this.name} is walking`);
}
}
class Student extends Person {
constructor(name: string) {
super(name)//直接使用父类的构造方法
}
work() {
console.log(`${this.name} is working hard`);
}
walk() {
console.log(`${this.name} walking with his father`);
}
}
let s1 = new Person('zhangsan');
const sentence:string=s1.run()
console.log(sentence);
let s2 = new Student('lisi')
const sentence2: string = s2.run();
console.log(sentence2);
s2.work()
s2.walk()
22、类里面的修饰符
public:共有,类内部,子类,类外面
protected:保护类型 在类里面,子类里面可以访问,外部不可以
private:私有 类内部
基本同java
23、静态方法和静态属性
class Person {
name: string;
static age: number;
constructor(name: string) {
this.name = name;
}
run(): string {
return `${this.name} is moving`
}
static walk():void {
console.log(`person is walking`);
}
}
let p1 = new Person('zhangsan');
Person.walk();
Person.age = 19;
console.log(Person.age);
24、多态
父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现
基本同java
下面是重写父类方法实现多态
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
eat() {
console.log('eat method');
}
}
class Student extends Person {
constructor(name:string) {
super(name)
}
eat() {
console.log(`${this.name} eat at student room`);
}
}
class Teacher extends Person {
constructor(name:string) {
super(name)
}
eat() {
console.log(`${this.name} eat at teacher room`);
}
}
let s1 = new Student('zhangsan');
let t1 = new Teacher('lisi');
s1.eat();
t1.eat();
25、abstract抽象类
用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
抽象方法只能放在抽象类里面
抽象类只能作为子类的基类,不能被实例
abstract class Animal {
name: string;
constructor(name:string) {
this.name = name;
}
abstract eat():void;
}
class Dog extends Animal {
//这里没有应用父类的构造函数super,但是依然将name属性继承到dog类中来了
eat():void {
console.log(`${this.name}dog eat meat`);
}
}
let d1 = new Dog('wangcai ');
d1.eat();
26、interface接口–属性接口
interface接口和java的interface接口很不一样
- 1、属性接口是对json的约束
对参数进行约束,传入一个对象参数,参数对象的key名一定要注意使用正确
function printLabel(labelInfo: {label:string}): void {
console.log(`${labelInfo.label}`);
}
printLabel({label:'sunwukong'})
- 2、对批量方法传入参数进行约束(应该是方法批量传入参数)
interface FullName {
FirstName: string;
secondName: string;
}
//这个方法实现接口,没有类implement,和java不一样
function printName(name: FullName) { 体现在参数的类型上实现了接口
console.log(name.FirstName+'--'+name.secondName);
}
printName({
FirstName: 'zhang',
secondName:'san'
})
let obj = {//对象的成员需要包含FirstName和secondeName两个参数
age: 20,
FirstName: 'zhang',
secondName:'san'
}
printName(obj)
27、interface接口–可选属性接口
interface FullName {
FirstName: string;
secondName?: string;//实现该参数可传可不传
}
//这个方法实现接口,没有类implement,和java不一样
function printName(name: FullName) { //体现在参数的类型上实现了接口
console.log(name.FirstName+'--'+name.secondName);
}
printName({
FirstName: 'zhang',
//secondName:'san'
})
let obj = {//对象的成员需要包含FirstName和secondeName两个参数
age: 20,
FirstName: 'zhang',
secondName:'san'
}
printName(obj)
28、封装ajax
interface Config {
type: string;
url: string;
data?: string;
dataType: string;
}
function ajax(config: Config) {
var xhr =new XMLHttpRequest();
xhr.open(config.type,config.url, true);
xhr.send(config.data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (config.dataType == 'json') {
JSON.parse(JSON.parse(xhr.responseText));
} else {
console.log(xhr.responseText);
}
}
}
}
ajax({
type: 'get',
data: 'name=zhangsan',
url: 'http://a.itying.com/api/productlist',
dataType:'json'
})
29、函数类型接口
对方法传入的参数,以及返回值进行约束
interface encrypt {
(key: string, value: string): string;//的函数类型
}
var md5: encrypt = function(key: string, value: string): string{
//模拟操作
return key + value;
}
console.log(md5('name', 'zhangsan'));
var myjiami: encrypt = function (key: string, value: string): string {
return key + value +'-----'
}
console.log(myjiami('nceee', 'huamnc'));
30、可索引接口:数组和对象的约束
interface UserArr {
[index: number]: string;
}
var arr: UserArr = ['zhagnsan', 'lisi', 'wanger']
console.log(arr[0]);
interface UserObj {
[index:string]: string;
}
var myboj: UserObj={
'name': 'zhagnsan',
'age': '19',//年龄不能是数字而应该是字符串
'address':'beijign'
}
console.log(myboj.address);
31、类类型接口:对类的约束(和抽象类有点相似)
和java的interface接口才是真正的一致
interface Animal {
name: string;
eat(str: string): void;
}
class Dog implements Animal {
name: string;
constructor(name:string) {
this.name = name;
}
eat(food: string) {
console.log(`${this.name} eat ${food}`);
}
}
let d1 = new Dog('wagncai');
d1.eat('meat');
32、接口的扩展(接口继承接口)
interface Animal {
eat(food: string): void;
}
interface Person extends Animal {
work(): void;
}
class senior {
garde: number;
constructor(grade: number) {
this.garde = grade;
}
}
class Student extends senior implements Person{
name: string;
grade: number;
constructor(name: string,grade: number) {
super(grade);
this.name = name;
this.grade = grade;
}
eat(food: string) {
console.log(`student ${this.name} of ${this.grade} eat ${food}`);
}
work():void{
console.log(`student ${this.name} of ${this.grade} work hard`);
}
}
let s1 = new Student('zhagnsan',3);
s1.eat('dacan');
s1.work();
33、泛型
泛型就是解决类、接口、方法的复用性,以及对不特定数据类型的支持
any放弃了类型检查,这点并不好
泛型:可以支持不特定的数据类型,要求,插入的参数和返回的参数一致
//三个t的需要同时为泛型类型(t)类型,具体是什么类型在调用的时候决定,而不是在定义的时候决定
function getData<T>(value: T): T {
return value;
}
const myvalue: number = getData<number>(123);
console.log(typeof myvalue);
const myvalue2: string = getData<string>("zhangsan");
console.log(typeof myvalue2);
34、泛型类
class MiniClass<T> {
public list: T[] = [];
add(num: T) {
this.list.push(num);
}
min():T {
var minNum = this.list[0];
for (var i = 0; i < this.list.length; i++) {
if (minNum > this.list[i]) {
minNum = this.list[i];
}
}
return minNum;
}
}
var mynumber = new MiniClass<number>();//使用<number>表示把number类型替代T类型,不写会默认替代
mynumber.add(1);
mynumber.add(4);
mynumber.add(5);
mynumber.add(8);
mynumber.add(3);
console.log(mynumber.min());
var mynumber2 = new MiniClass<string>();//使用<string>表示把string类型替代T类型,不写会默认替代
mynumber2.add('r');
mynumber2.add('g');
mynumber2.add('y');
mynumber2.add('j');
mynumber2.add('k');
console.log(mynumber2.min());
35、泛型接口
第一种方法:T放在接口体内
interface ConfigFn {
//定义一个函数接口
<T>(value: T): T;
}
var getData:ConfigFn= function<T> (value: T): T {
return value;
}
//类型在调用时确定
console.log(getData('zhang'));
console.log(getData(124.255));
第二种方法:T放在接口名称后
interface ConfigFn<T> {
//定义一个函数接口
(value: T): T;
}
function getData<T> (value: T): T {
return value;
}
//类型在调用时确定
console.log(getData('zhang'));
console.log(getData(124.255));
36、把类(实例)作为参数
- 定义一个User类,这个类的作用就是映射数据库字段
- 在定义一个Mysql类,这个类的用作操作数据库
- 然后把User类作为参数传到MysqlDb中去
class User {
username: string | undefined;
password: string | undefined;
}
class MysqlDb {
add(user: User): boolean {
console.log(user.username, user.password);
return true;
}
}
let user1 = new User();
user1.username = 'zhangsan';
user1.password = '123456';
let db = new MysqlDb();
db.add(user1);
另外一例
class ArticleCate {
title: string | undefined;
desc: string | undefined;
status: number | undefined;
}
class MysqlDb {
add(info: ArticleCate): boolean {
console.log(info.title, info.desc,info.status);
return true;
}
}
let info = new ArticleCate();
info.title = 'mytile';
info.desc = 'some describe';
info.status = 577;
let db = new MysqlDb();
db.add(info);
使用泛型来实现,避免重复封装
class MysqlDb<T> {
add(info: T): boolean {
console.log(info);
return true;
}
}
class ArticleCate {
title: string | undefined;
desc: string | undefined;
status: number | undefined;
constructor(params: {
title: string | undefined,
desc: string | undefined,
status: number | undefined,
} ) {
this.title = params.title;
this.desc = params.desc;
this.status = params.status;
}
}
class User {
username: string | undefined;
password: string | undefined;
}
let user1 = new User();
user1.username = 'zhangsan';
user1.password = '123456';
let db1 = new MysqlDb<User>();//构造的时候要把确定的类型传入
db1.add(user1);
let info = new ArticleCate({
title: 'mytile',
desc: 'some describe',
status: 577
});
let db2 = new MysqlDb<ArticleCate>();//构造的时候要把确定的类型传入
db2.add(info);
37、封装统一操作Mysql Mongodb Mssql的底层库(综合使用类型、接口、类、泛型)
需求:
定义一个操作数据库的库,支持mysql,msql mongodb
要求:
1、mysql,mysql,mongodb功能差不多,都有add update delete get方法
注意:约束统一规范,以及代码重用
解决方案:需要约束规范所以需要定义接口,需要代码重用所以用到泛型
1、接口:在面向对象的编程中,接口是一种规范的定义,她定义了行为和动作的规范
2、泛型:通俗理解:泛型就是解决 类,接口,方法的复用性。
//定义接口
interface DBI<T> {
add(info:T): boolean;
update(info:T,id:number): boolean;
delete(id:number): boolean;
get(id:number): any[];
}
//定义一个操作mysql数据库的类, 要实现泛型接口,这个类也应该是一个泛型类
class MySqlDb<T> implements DBI<T> {
constructor() {
//数据库建立连接,模拟,本代码不影响结果
console.log('db connect is already build');
}
add(info: T): boolean {
console.log(info);
return true;
}
update(info: T,id:number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
//模拟一下数据库返回的数据
var list = [
{
title: '1xxxx',
desc:'1xxxxxx===xxxxx'
},
{
title: '2xxxx',
desc:'2xxxxxx===xxxxx'
},
{
title: '3xxxx',
desc:'3xxxxxx===xxxxx'
}
];
return list;
}
}
//定义一个操作mssql数据库的类, 要实现泛型接口,这个类也应该是一个泛型类
class MsSqlDb<T> implements DBI<T> {
add(info: T): boolean {
console.log(info);
return true
}
update(info: T,id:number): boolean {
throw new Error("Method not implemented.");
}
delete(id: number): boolean {
throw new Error("Method not implemented.");
}
get(id: number): any[] {
throw new Error("Method not implemented.");
}
}
//给用户表添加数据,定义一个User和数据表映射类
class User {
username: string | undefined;
password: string | undefined;
}
let user = new User();
user.username = 'zhangsan';
user.password = '123456';
let dbMysql = new MySqlDb<User>();//类作为参数来约束数据传入的类型
dbMysql.add(user);
//使用Mssql数据库
let user2 = new User();
user2.username = 'lisi';
user2.password = '654321';
let dbMssql =new MsSqlDb<User>();
dbMssql.add(user2)
//获取id表里面等于4的数据
let data = dbMysql.get(1);
console.log(data);