介绍ts
JS 的超集 javascript 轻量级的变量约束 支持在任何支持JavaScript的平台执行 添加很多类型 提高大型项目的可维护性
最终会编译成JS。类似于预编译的处理类似于less,scss
搭建开发环境
1.下载Node.js
64位: https://nodejs.org/dist/v14.15.1/node-v14.15.1-x64
32位: https://nodejs.org/dist/v14.15.1/node-v14.15.1-x86
2.安装Node.js
3.使用npm全局安装typescript
。进入命令行
。输入: npm i-g typescript
4.创建一个ts文件
5.使用tsc对ts文件进行编译
进入命令行
进入ts文件所在目录
执行命令:
对ts进行解析
tsc xxx.ts
ts类型
:后面指定类型 直接赋值ts可以检测到类型
let a:number
//指定a的类型为number
let c:boolean=true
//指定完变量直接赋值
//可以把boolean去掉 ts可以对变量进行类型检测
function sum(a:number,b:number){
return a+b;
}
any和unkown的区别是unkown不能直接赋值给其他变量 需要转化
let z:string
//用|实现多个类型(联合类型)
let q:'male'| 'female'
//对其关闭了类型检测
//如果不写ang 称为隐式的ang
let t:any
let s:string
s=t
//ang的变量也可以影响别的变量
let e:unknown
let p:string
//p=e
// 1 unkown不能直接赋值给其他变量
if(typeof e==='string'){
s=e
}
// 2 类型断言
s=e as string
// s=<string> e
ts对象
构造函数和对象的声明
let a2:{name:String}
//语法{属性名:属性值}
// 属性名后面加上?:代表可选的
let b:{name:string,age?:number}
b={name:'qaq',age:18}
//[propeName:string]:ang表示任意类型的属性
let c2:{name:string,[propName:string]:any}
c2={name:"qqq",age:18,gender:'男'}
//设置函数结构体的类型申明
//(形参:类型,形参:类型)=>返回值
let d:(a:number,b:number)=>number
d=function(a:number,b:number):number{
return 10
}
数组
//字符串数组
let f:string[]
f=['a','b','c']
let g:Array<number>
g=[1,2,3]
编译的配置
配置文件
tsconfig.json是ts编译器的配置文件,ts编译器可以根据它的信息来对代码进行编译
“include” 用来指定哪些ts 文件需要被编译
路径: ** 表示任意目录
*表示任意文件
"exclude"不需要被编译的
默认值:[“node_modules”,“bower_components”,“jspm_packages”]
罗列了一些常见的配置
{
"include": [
"./src/**/*"
],
"exclude": [
"./src/hello/**/*",
"node_modules",
"bower_components",
"jspm_packages"]
,
"compilerOptions": {
"target":"ES6",
"module": "ES2015",
// "lib": ["es5","DOM"],
//指定编译后文件 所有全局作用域中会合并一个 不能使用模块化
//"outDir": "./dist/app.js" module": "system",
"outDir": "./dist",
//对js不编译
"allowJs":false,
//是否检查js代码
"checkJs": false,
//注释
"removeComments": false,
//不生成编译后的文件
"noEmit": false,
//有错误不生成编译后的文件
"noEmitOnError": true,
//严格模式"use strict";
"alwaysStrict": true,
//不允许隐式类型
"noImplicitAny": false,
//不允许不明确的this
"noImplicitThis": false,
//所有检查 建议设置为true
"strict": false
}
}
类
有一说一 ts和java很像 都是面向对象编程
下面创建了一个person类 包含了方法和属性
//类包含了属性和方法
class Person{
name:String='哈哈哈'
age:Number=18
//类属性
static sex:Number=18
//只读的属性
readonly sex1:Number=18
//------方法
sayHello(){
console.log('hello');
}
}
const pre=new Person();
//直接定义的是实例属性 如pre.age
//加上static是类属性 静态属性
console.log(Person.sex);
console.log(pre.age);
console.log(pre.sayHello);
构造函数
constructor的this就指向当前实例 可以通过this往对象中添加属性
class Dog{
name:string;
age:number;
constructor(name:string,age:number){
//在实例方法中 this表示当前实例
//构造函数中当前对象就指向实例对象 可以通过this
//向新建的对象中添加属性
this.name=name;
this.age=age;
}
break(){
alert('wang')
}
}
const dog1=new Dog('小黑',4)
使用extends继承
class 子类 extends 父类 可以通过这个语句继承子类的方法和属性 有父类没有的方法同时也可以对父类的方法覆盖
(function(){
class Anima{
name:string
age:number
constructor(name:string,age:number){
this.name=name;
this.age=age;
}
sayHello(){
console.log('qaq');
}
}
class Dog extends Anima{
//继承
//子类独有
run(){
console.log('hahah',`${this.name}`);
}
//子类覆盖掉父类的方法 叫重写
sayHello(): void {
}
}
const dog=new Dog('1111',1);
})
super关键字 对父类的构造函数的调用
(function(){
class Anima{
name:string
age:number
constructor(name:string,age:number){
this.name=name;
this.age=age;
}
sayHello(){
console.log('qaq');
}
}
class Dog extends Anima{
constructor(name:string,age:number){
//如果在子类写了构造函数 在子类构造函数中必须对父类的构造函数进行调用
super(name,age)//调用父类的构造函数
this.age=age
}
sayHello(): void {
super.sayHello()
//在类方法中 super就表示当前类的父类
}
}
})()
接口
相当于定义一个标准 使得类按照这个标准去创建 接口只提供标准 不涉及具体的值
可以通过implements 去继承这个标准
//对对象类型进行限制
(function(){
type myType={
name:string,
age:number
}
const obj:myType={
name:'sssss',
age:11111
}
//接口 用来定义一个类的结构 定义类中应该包含哪些属性和方法
//同时接口也可以当成类型声明去使用
//如果重名 会合并 限制类的结构
//接口只定义结构 不考虑实际值
interface myInterfacee{
name:string,
age:number,
sayHello():void
}
// const obj2:myInterfacee={
// name: "'222",
// age: 1111,
// sayHello: function (): void {
// throw new Error("Function not implemented.")
// }
// }
//定义类 可以使类去实现一个接口 实现了一个标准
class myclass implements myInterfacee{
name: string
age: number
constructor(name:string,age:number){
this.name=name;
this.age=age
}
sayHello(): void {
console.log('大家好');
}
}
})()
属性的封装
有三种修饰符 修饰符 public可以在任意位置进行访问修改 private私有属性 只能在内部进行访问修改protected 受保护的 能在子类和原有类访问
因为有些属性常常不能被修改 但是可以通过类里面的方法访问到属性
像 getName() 和 setValue()
(function(){
class Person {
//修饰符 public可以在任意位置进行访问修改
//private私有属性 只能在内部进行访问修改
//protected 受保护的 能在子类和原有类访问
//---通过类里面的方法使得私有属性可以被外部访问 不能在实例访问
private name:string
age:number
constructor(name: string,age: number){
this.name=name
this.age=age
}
getName(){
return this.name
}
setValue(val: string){
if(val){
return this.name
//所以可以对传入的数据进行判断
}
this.name=val
}
}
const per=new Person('孙悟空',18)
//这样可以修改属性 堆属性不安全
// per.age=39
console.log(per.getName());
})
同时ts提供了一个简洁的写法 直接对象.方法名 可以通过这个方式设置
get name(){
return this._name
}
set name(val){
this._name=val
}
(function(){
class Person {
private _name:string
_age:number
constructor(name: string,age: number){
this._name=name
this._age=age
}
//ts设置get
get name(){
return this._name
}
set name(val){
this._name=val
}
}
const per=new Person('孙悟空',18)
//直接读取
per.name='我改名字了'
console.log(per.name);
})
泛型
当类型不明确时候 使用的 可以通过运行的时候推断也可以通过指定泛型实现 同时可以继承接口 例如
function fn2<T extends Inter>(a:T):number{
return a.length
}
下面是例子
function fn<T>(a:T):T{
return a;
}
fn(20)//在运行的时候自动推断
fn<string>("hello")//指定泛型
interface Inter{
length:number
}
function fn2<T extends Inter>(a:T):number{
return a.length
}
//T extends Inter 表示泛型T必须使inter的实现类
fn2({length:10})
总结
感觉ts和java很像 先学ts的原因是因为以后写代码需要更准确类型限制的时候自己还不会 下一阶段打算学react