typescript入门
Posted genhao7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了typescript入门相关的知识,希望对你有一定的参考价值。
安装解析工具
-
npm install typescript -g
-
运行
tsc 文件名.md
,将ts文件编译成一个同名js文件
注释
与js用法相同
变量赋值
- js
let 变量名=值
- ts
let 变量名: 数据类型=值
数据类型
基本数据类型(原始类型),复杂数据类型(对象类型)
js中的类型
-
number
let age: number=18
-
string
let name: string =‘Tom‘
-
boolean
let isPass: boolean =true
-
undefined
let un: undefined=undefined
-
null
let nu: null =null
-
对象与数组
-
array:
let arr: string[]=[‘a‘,‘b‘,‘c‘]
let arr: number[]=[18,19,20]
? 泛型
let arr: Array<string>=[‘a‘,‘b‘,‘c‘]
let arr: Array<number>[]=[18,19,20]
-
function:
function sayHi():string{ return ‘hi‘ } let a=sayHi()
function sayHi():void{ console.log(‘hi‘) }
-
新增类型
-
tuple: 元组 ---> 规定了数组中的元素数量和每个元素的数据类型类型, 类型可以不相同
? 创建
let tup1:[number,string,boolean]=[1,‘Tom‘,true]
? 重新赋值
tup1=[2,‘jack‘,false]
? 获取元素
tup1[0]
,tup1.length
-
enum:枚举
? 创建
enum Gender{ boy, girl, unknow }
? 使用
console.log(Gender.boy)
? 赋值
let sex:Gender = Gender.boy
-
any:任意类型,一般用于获取DOM对象
let txtName: any=document.getElementById(‘txt‘)
-
never: 不存在的值的类型,常用于抛出异常,或者无限循环的函数安徽类型
function test():never{ while(true){ } }
function test():never{ throw new Error(‘错误!‘) }
-
void:没有类型,用于无返回值的函数
类型的推断
如果变量的声明个初始化是在同一行,可以省略掉变量类型的声明
let 变量名 = 值
----------> let 变量名: 变量类型 = 值
let age=18
-----------> let age: number =18
联合类型
变量的取值可以是多种类型中的一种
let 变量名: 变量类型1 |变量类型2 = 值
--------------> let name :string | null =prompt(‘输入名字‘)
name可以是 String或者 Null类型
函数
返回值和类型
函数必须有返回值类型
实参形参类型必一致
实参形参数量必须一致
function sayHi(words: string) :void{
console.log(words)
}
sayHi(‘hello‘)//hello
可选参数
可选参数的实参可传可不传
function sayHi(words?:string):void{
console.log(words)
}
sayHi()//undefined
默认值(可替换可选参数)
同ES6函数的默认参数
function sayHi(words=‘hello‘): void{
console.log(words)
}
sayHi()
sayHi(‘world‘)
有时候只传需要传第二个参数,这种情况只需把第一个参数设置成 undefined
即可
剩余参数
形参数量不确定的情况,比如一个加法运算不确定参数的个数
function add(形参1:类型1,形参2:类型2,...形参3:类型[]):void{
}
剩余参数只能定义一个
剩余参数只能定义成一个数组
剩余参数只能写在形参列表的最后
function add (x:number,y:number,...restOfNum:number[]):void{
let resNum: number =x+y;
for(let item of restOfNum){
resNum+=item
}
console.log(resNum)
}
add(1,2) //3
add(1,2,3,4,5) //15
类和对象
创建对象
- 原生js
function City(cName, cLevel) {
this.cName = cName;
this.cLevel = cLevel;
}
City.prototype.about = function() {
console.log(this.cName, this.cLevel);
};
const city = new City(‘shanghai‘, 1);
city.about();//shanghai , 1
- ts
class City {
cName: string;
cLevel: number;
constructor(cName: string, cLevel: number) {
this.cName = cName;
this.cLevel = cLevel;
}
about() {
console.log(this.cName, this.cLevel);
}
}
const city = new City(‘shanghai‘, 1);
city.about();//shanghai , 1
继承
- 父类
class City {
cName: string;
cLevel: number;
constructor(cName: string, cLevel: number) {
this.cName = cName;
this.cLevel = cLevel;
}
about() {
console.log(this.cName, this.cLevel);
}
}
- 子类
class Area extends City{
constructor(cName, cLevel) {
super(cName,cLevel);
}
}
const area =new Area(‘shanghai‘,1);
area.about() //shanghai 1
多态(类似于重写)
父类定义一个方法不去实现,让继承的子类去实现,每个子类都有不同的表现
//定义父类
class Animal_Plant{
eat(f){
console.log(‘cannt eat‘)
}
}
//对eat方法进行重写
class Dog extends Animal_Plant{
eat(f){
console.log(‘can eat‘ ,f)
}
}
class Flower extends Animal_Plant{
}
let dog =new Dog()
dog.eat(‘meat‘) //can eat meat
let flower =new Flower()
flower.eat(‘something‘) //cannt eat
- 父类定义方法,子类继承,实现不同的效果
- 子类如果不实现这个方法的话,也能够使用父类中默认的
修饰符
- public :公有类型----->类、子类、类外面都能够访问,属性和方法默认是
public
- protected:保护类型----->类,子类中能够访问,类外面不能访问
- private:私有类型---------->只有在类里面能够访问,其余都不能访问
class Animal {
public name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal(‘Jack‘);
console.log(a.name); // Jack
a.name = ‘Tom‘;
console.log(a.name); // Tom
抽象类---abstract
abstract class Animal {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
}
class Cat extends Animal {
public sayHi() {
console.log(`Meow, My name is ${this.name}`);
}
}
let cat = new Cat(‘Tom‘);
- 抽象类不能实例化,只能通过子类继承
- 类中若存在抽象方法,也必须在子类中实现
个人理解抽象类是一个骨架,一个模板,必须通过子类去填充,去实现具体的细节
静态属性和方法---static
class City {
cName: string;
cLevel: number;
static isNearTheSea = true;
constructor(cName: string, cLevel: number) {
this.cName = cName;
this.cLevel = cLevel;
}
about() {
console.log(this.cName, this.cLevel);
}
static location() {
console.log(‘中国‘);
}
}
City.location();//中国
console.log(City.isNearTheSea);//true
- 静态方法和属性不需要实例化对象,可以直接调用
- 静态方法不能调用类里面的属性
- 静态方法可以调用类里面的静态属性
接口
属性接口
- 基本操作
interface Name {
label: string;
}
function setName(nameObj: Name) {
console.log(nameObj.label);
}
//调用时,实参类型与接口一致,属性的类型必须一致,且必须包含这个属性
setName({
label:‘xiaohong‘
})//输出 xiaohong
- 额外传入参数
interface Name {
label: string;
}
function setName(nameObj: Name) {
console.log(nameObj.label);
}
//在外部单独定义一个对象,可有额外的属性,但必须包好接口中定义的属性
let obj={
label :‘xiaohong‘,
age:18,
}
setName(obj)
- 属性不定,可选
//定义接口时,在不确定的属性后面加上问号 ?
interface Name {
label: string;
isEnglishName? :boolean
}
函数接口
- 基本操作
interface eat{
(name:string,food:string):void
}
let breakfast:eat =function(name:string,food:string){
console.log(name,food)
}
breakfast(‘早饭‘,‘包子‘)//早饭 包子
- 可选参数
interface eat{
(name:string,food?:string,):void//可选加上 ?
}
let breakfast:eat =function(name:string,food=‘没吃‘){//给一个默认值,否则输出 undefined
console.log(name,food)
}
breakfast(‘早饭‘)
- 不定参数
interface eat{
(name:string,...food:string[]):void
}
let breakfast:eat =function(name:string,...food:string[]){
console.log(name,food.join())
}
breakfast(‘早饭‘,‘包子‘,‘豆浆‘,‘油条‘)//早饭 包子,豆浆,油条
类接口-----implements
interface Animal {
name: string;
eat(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
eat() {
console.log(this.name);
}
}
let dog = new Dog(‘xiaohei‘);
dog.eat()
接口继承接口
interface Alarm {
alert(): void;
}
interface LightableAlarm extends Alarm {
lightOn(): void;
lightOff(): void;
}
泛型
函数泛型
function getData<T>(value:T):T{
return value
}
function getData<T>(value:T):void{
// return value
console.log(value)
}
类的泛型
接口的泛型
第一种写法
interface Config {
<T>(value:T):T;
}
let getDate:Config =function<T>(value:T):T{
return value
}
console.log(getDate<number>(1212))
第二种写法
interface Config<T> {
(value:T):T;
}
function getData<T>(value:T):T{
return value
}
let myGetData:Config<string> = getData
console.log(myGetData(‘xiaohong‘))
命名空间
解决命名重复的问题
- 封装命名空间
namespace A{
//namespace 里面默认时私有的,外部使用时需要用export 暴露出来
export class Dog{
...
}
...
}
namespace B{
export class Dog{
...
}
export ...
}
- 使用
let adog=new A.Dog()
adog.eat()
let bdog =new B.Dog()
bdog.eat()
封装使用命名空间
可以把命名空间抽离出来,放入一个ts文件中,然后通过export暴露到外部
//新建module.ts
export namespace A{
export class Dog{...}
...
}
export namespace B {
export class Dog{...}
export class Cat{...}
...
}
//外部使用
import {A,B} from ‘module.ts‘
let adog=new A.Dog()
adog.eat()
let bdog =new B.Dog()
bdog.eat()
装饰器
装饰器是 一个方法,可以注入到类,方法,属性,参数上来拓展类方法,属性,参数的功能
类装饰器
属性装饰器
方法装饰器
参数装饰器
普通装饰器(不能传参)
function logClass(params:any){
console.log(param)// 当前类
params.prototype.url=‘XXX‘//添加一个属性
params.prototype.get=function(){//添加一个方法
}
}
@logClass
class HttpClient{
construtor(){
}
getData(){
}
}
工厂装饰器(可传参 推荐使用)
function logClass(params:string){
return function (target:any){
console.log(target) //当前类
console.log(params) // hello world
}
}
@logClass(‘hello world‘)
class MyHttp{
constructor(){
}
getData(){
}
}
let http:any =new MyHttp()
以上是关于typescript入门的主要内容,如果未能解决你的问题,请参考以下文章
typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming
typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming