1.什么是typescript:
它是一个强类型的JavaScript超集,typescript是拥有类型的javaScript超集, 它可以编译成普通\干净\完整的js代码 ES3,js所拥有的内容ts都支持, 并且js有es678... ts也都支持这些语法,ts拥有独特的一些数据类型 枚举 元组 void any
2.我们为什么需要TypeScript?
- TypeScript快速、简单,最重要的是,容易学习。
- TypeScript支持面向对象的编程特性,比如类、接口、继承、泛型等等。
- TypeScript在编译时提供了错误检查功能。它将编译代码,如果发现任何错误,它将在运行脚本之前突出显示这些错误。
- TypeScript支持所有JavaScript库,因为它是JavaScript的超集。
- TypeScript通过使用继承来支持可重用性。
- TypeScript使应用程序开发尽可能的快速和简单,并且TypeScript的工具支持为我们提供了自动完成、类型检查和源文档。
- TypeScript支持静态类型、强类型、模块、可选参数等。
3.typescript的优缺点
优点
- 它提供了可选静态类型的优点。在这里,Typescript提供了可以添加到变量、函数、属性等的类型。
- Typescript能够编译出一个能在所有浏览器上运行的JavaScript版本。
- 它使用基于类的面向对象编程。
- TypeScript总是在编译时强调错误,而JavaScript在运行时指出错误。
缺点
- 如果我们在浏览器中运行TypeScript应用程序,需要一个编译步骤将TypeScript转换成JavaScript。
- 要使用任何第三方库,必须使用定义文件。并不是所有第三方库都有可用的定义文件。
- TypeScript不支持抽象类。
typescript的安装和使用?
两个指令都要安装到全局
第一步安装ts
cnpm/npm install -g typescript? ?
第二部运行typescript的指令
cnpm/npm?install -g ts-node
ts文件可以解析编译成js
指令:tsc-node xxxx.ts选择你要解析的ts文件
ts文件运行指令
ts-node xxxx.ts选择你要运行的文件
运行过后他会给你报错tsc --init 命令进行基本的初期化
?4.typescript中的内置类型
在ts中声明变量 需要使用类型注解的形式在js中我们对变量没有定义过它的值是什么
经常 let num=100或者 let str="哈哈"
ts自身会有类型检测机制
类型注解的形式
var num: number = 100; var num:string
我们在鼠标放到变量上面会显示他声明的他是什么类型
那什么时候需要添加类型注解
默认情况下 ts会帮我们将初始赋值的数据类型作为当前变量的类型
类型推导
这个是没有添加类型注解的形式,我们虽然没有给他添加类型注解但是ts本身它会给我们推导他是什么类型
let name2 = 789;let name2:number
number类型
let num: number = 123;
string类型
let name: string?= "哈喽!";
布尔类型
let flag: boolean = true;
在ts中 null和undefined
var n = null;
var u = undefined;
n = null;
n = undefined;
在ts中 null和undefined他们是类型 也是值
数组类型
let arr2: string[] = [];?
let arr3 = ["xxx",18, true];
any类型
let msg: any = "1234";
msg = 123;
msg = true;
msg = [];
msg = null;
它可以是任何类型但是它也会失去某些数据
unknown类型 只能赋值给any和unknown类型的变量
any类型 可以赋值给任意类型的变量
let flag = true;
let res: unknown;
if(flag){
res = fn1();}else {res = fn2();}
let msg:unknown = res;
console.log(res)
Void类型: Void是不返回任何类型值的函数的返回类型。如果没有可用的数据类型,则使用它。
枚举类型
就是将一组可能出现的值, 一个一个列举出来, 定义在一个类型中,这个类型就是枚举类型
枚举类型放常量 字符串 数字 (全大写)
5.stpescript中的函数
type Fn = (qwerty)=>void
let fn:Fn = function (){return "aaaa"}
ts中的this指向谁调用它它的this就是谁
函数中剩余的参数可以通过...es6新增的展开运算符
函数的重载
//函数签名 通过函数签名的形式来实现函数重载
function sum(a1:number, a2:number): number;
function sum(a1:string, a2:string): string;
function sum(a1: any, a2: any){
return a1+a2
}
//在调用sum函数的时候,它会根据我们传入的参数类型,来决定执行函数时,到底执行哪一个函数签名
sum(1,2);//3
sum("1","2");//"12"
//有重载的情况下,那么哪怕数据类型是any只要不符合任意一个重载函数签名,那么都是不能使用的
// sum({a1:1},{a2:2});//"12"
//通过函数重载来实现效果
function getLength(arg: string): number;
function getLength(arg: any[]): number;
function getLength(arg: any){return arg.length}
getLength("wertyuio");
getLength([1,2,3,4,5]);
//在可能的情况下,尽量来选择通过联合类型去实现
6.typescript泛型
泛型的理解 在开发中我们经常使用函数的时候数据需要定义不同的类型 而且也要考虑它的可重用性 在定义这个函数的时候, 我们不去管参数的类型而是让调用者以参数的形式告诉我们函数的参数应该是什么类型 通过泛型的形式来确定变量的数据类型 函数中在函数名的后面通过<t>的形式,接受传递过来的类型 T: type的缩写, 类型 或者可以在通过字面量类型<t=string>直接写死
//泛型函数
//函数中在函数名的后面通过<形参>的形式,接受传递过来的类型
function fn<T=string>(arg:T):T{
console.log(arg)
return arg
}
//泛型函数调用
//1通过<类型> 的方式将类型传递给函数
fn<string>("1234")
//2通过类型推导,自动的推导出我们传入变量的类型
// 在这里会推导出他们是字面量类型, 当然字面量类型对我们的函数也是适用的
fn<number>(123)
//引用类型会推导出想要的效果
fn<number[]>([1,2,3])
fn({a:1})
fn([1,2,3])
//通过泛型的形式来确定变量的数据类型
let arr: string[] = ["1","2","3"]
let arr1: Array<string> = ["1","2","3"]
let arr2: Array<number> = [1,2,3,4]
泛型约束 在大多时候我们虽然知道某些数据的参数但是我们想打印它的lengts长度但是ts并不能解析他的长度属性我们就可以自定义一个接口并且接口里面有length属性的接口我们就可以用到extends 是实现约束?
//只要是拥有length的属性 都可以作为我们当前函数的参数类型
interface ILength{
length: number
}
function getLength<T extends ILength>(arg:T):number{
let num = arg.length
console.log(num)
return num
}
getLength<string>("1234")
getLength<number[]>([1,2,3,4])
getLength<{[name:string]:number,length:number}>({a:1,length:1})
?
7.typescript中的类
类的继承 类开头大写
class Person{
name!:string;
age:number;
constructor(name:string, age:number) {
this.name = name;
this.age = age;
}
running(){
console.log(this.name + " running")
}
eating(){
console.log(this.name + " eating")
}
}
let p = new Person("ES6+",7)
p.running()
p.eating()
类中的继承?
class Person{
name!:string;
age:number;
constructor(name:string, age:number) {
this.name = name;
this.age = age;
}
running(){
console.log(this.name + " running")
}
eating(){
console.log(this.name + " eating")
}
}
class A{}
//Classes can only extend a single class.
// class Student extends Person, A{
class Student extends Person{
learn: string;
constructor(name:string, age:number, learn: string) {
super(name, age);
this.learn = learn
}
running(){
//this ==> s
//super===> Person
super.running()
console.log(this.name + " Student running")
}
}
let s: Student = new Student("学生", 20, "TypeScript");
s.running();
s.eating();
console.log(s)
typescript中的成员访问
//在typeScript中 类的属性和方法支持三种修饰符
//1 public
// 修饰的是在任何地方可见 公有的属性或方法 默认编写的属性就是public的
//2 private
// 修饰的是仅在同一类中可见 私有的属性或方法(不参与继承)
//3 protected
// 修饰的是仅在类自身及子类中可见 受保护的属性或方法(不能读写)
public方法?
class Person {
public name!: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
running() {
console.log(this.name + " running")
}
eating() {
console.log(this.name + " eating")
}
}
let A = new Person('rrr',777)
console.log(A);
private方法
//private 修饰
class Person{
private name:string;
constructor(name:string) {
this.name = name;
}
}
let p = new Person("aa");
console.log("=======>",p)
protected方法
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
let p = new Person("aa");
class Student extends Person {
constructor(name: string) {
super(name);
}
running() {
console.log(this.name + " Student running")
}
}
let A = new Person('aaa')
console.log(A);
|