一、介绍
TypeScript是一种由微软开发的开源、跨平台的编程语言。它是JavaScript的超集,最终会被编译为JavaScript代码。
2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript
TypeScript的作者是安德斯·海尔斯伯格,C#的首席架构师。它是开源和跨平台的编程语言。
TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以运行在TypeScript环境中。
TypeScript是为大型应用的开发而设计,并且可以编译为JavaScript。
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6+ 的支持**,它由 Microsoft 开发,代码开源于 GitHub 上。
二、特点
TypeScript 主要有 3 大特点:
- 始于JavaScript,归于JavaScript
TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 3(或更高版本)的JavaScript 引擎中。
- 强大的类型系统
类型系统允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。
- 先进的 JavaScript
TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性,比如异步功能和 Decorators,以帮助建立健壮的组件。
三、安装
#安装
brew install -g typescript
#验证版本
tsc -v
四、初识
1、类型注解
TypeScript 里的类型注解是一种轻量级的为函数或变量添加约束的方式。TypeScript提供了静态的代码分析,它可以分析代码结构和提供的类型注解。TypeScript 会警告你代码可能不会按预期执行。
(()=>{
function sayHello(name:string){
console.log(name+" Hello!");
}
//let myname = "BOB";
let myname =[1,2,3];//类型“number[]”的参数不能赋给类型“string”的参数。
sayHello(myname);
})()
2、接口
接口是一种能力,一种约束。
(()=>{
//定义接口
interface Iperson{
firstName:String
lastName:String
}
const person = {
firstName:"东方",
lastName:"不败",
show:function(){
console.log("this is my mac");
}
}
function showFullname(person:Iperson){
return person.firstName+"_"+person.lastName;
}
console.log(showFullname(person));
person.show();
})()
3、类
(()=>{
interface Iperson{
firstName:string;
lastName:string;
}
class person{
firstName:string;
lastName:string;
fullName:string;
constructor(firstName:string,lastName:string){
this.firstName = firstName;
this.lastName = lastName;
this.fullName = firstName +"_"+lastName
}
}
function getFullName(person:Iperson){
return person.firstName+"_"+person.lastName
}
let p = new person("紫霞","仙子")
console.log(getFullName(p));
})()
五、语法
1、基础类型
(()=>{
//布尔类型
let isdone:boolean = true;
console.log(isdone);
//数字类型,浮点数
let count:number = 10;
let sum:number = 0b1010;
console.log(count)
console.log(sum)
//字符串
let str1:string="窗前明月光"
let str2:string="地上鞋两双"
console.log(`--${str1},${str2}--`)
//undefined 和 null 默认情况下 null 和 undefined 是所有类型的子类型。
//就是说你可以把 null 和 undefined 赋值给其他类型的变量。
console.log(undefined)
console.log(null)
console.log(count=undefined)
//数组
let l1:number [] = [1,2,3]
let l2:Array<number> = [4,5,6]
let l3:string [] = ["java","python","typeScript"]
console.log(l1)
console.log(l3)
//元祖 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
//类型与位置相对应
let tp:[string,number,string] = ["ts",100,"good"];
console.log(tp)
//枚举
enum Color {
Red,
Green,
Blue
}
console.log(Color.Red);//0
console.log(Color[2])//blue
//any 任意类型
let l4:any [] = [1,"string",43];
console.log(l4)
//void void 类型像是与 any 类型相反,它表示没有任何类型
function getMSG():void{
//console.log("good good study")
return null;
}
console.log(getMSG());
//object 表示非原始类型,也就是除 number,string,boolean之外的类型。
function fn2(obj:object):object {
console.log('fn2()', obj)
return {}
// return undefined
// return null
}
console.log(fn2(new String('abc')))
// console.log(fn2('abc') // error
console.log(fn2(String))
//联合类型(Union Types)表示取值可以为多种类型中的一种
function getCount(st:string|number){
return st;
}
console.log(getCount("3333"))
//类型断言 通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。
/*
类型断言(Type Assertion): 可以用来手动指定一个值的类型
语法:
方式一: <类型>值
方式二: 值 as 类型 tsx中只能用这种方式
*/
/* 需求: 定义一个函数得到一个字符串或者数值数据的长度 */
function getLength(x: number | string) {
if ((<string>x).length) {
return (x as string).length
} else {
return x.toString().length
}
}
console.log(getLength('abcd'), getLength(1234))
//类型推断 类型推断: TS会在没有明确的指定类型的时候推测出一个类型
//1. 定义变量时赋值了, 推断为对应的类型. 2. 定义变量时没有赋值, 推断为any类型
let ss:string="666"
//ss = 666//error
let st;
st = "88"
st = 88
console.log(ss,st)
})()
2、接口
(()=>{
//定义接口
interface Iperson{
firstName:String
lastName:String
}
const person = {
firstName:"东方",
lastName:"不败",
show:function(){
console.log("this is my mac");
}
}
function showFullname(person:Iperson){
return person.firstName+"_"+person.lastName;
}
console.log(showFullname(person));
person.show();
//TypeScript 的核心原则之一是对值所具有的结构进行类型检查。
//我们使用接口(Interfaces)来定义对象的类型。接口是对象的状态(属性)和行为(方法)的抽象(描述)
/*
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型
接口: 是对象的状态(属性)和行为(方法)的抽象(描述)
接口类型的对象
多了或者少了属性是不允许的
可选属性: ?
只读属性: readonly
*/
interface Iper{
readonly id:number //只读
name:string //必须
age:number
sex?:string //可选
}
const per : Iper = {
id:123,
name:"bob",
age:13,
//sex:"nan"
}
//per.id = 99;
console.log(per.id)
//函数类型
//为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
//它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
interface serarch{
(str:string,st:string):boolean
}
const mySearch:serarch = function(str:string,st:string):boolean{
return str.search(st) > -1;
}
console.log(mySearch("java","a"))
//类类型 类实现接口 一个类可以实现多个接口 接口继承接口
interface Ifly{
fly()
}
class Plane implements Ifly{
//实现接口中的方法
fly() {
console.log("i can fly")
}
}
const f = new Plane();
f.fly();
//接口可以多继承
interface LightableAlarm extends Alarm, Light {
}
})()
3、类
(()=>{
interface Iperson{
firstName:string;
lastName:string;
}
class person{
firstName:string;
lastName:string;
fullName:string;
constructor(firstName:string,lastName:string){
this.firstName = firstName;
this.lastName = lastName;
this.fullName = firstName +"_"+lastName
}
}
function getFullName(person:Iperson){
return person.firstName+"_"+person.lastName
}
let p = new person("紫霞","仙子")
console.log(getFullName(p));
//继承 父类 子类
class Animal{
name:string
run(num:number){
console.log(this.name+" can run "+num+"m")
}
constructor (name:string){
this.name = name;
}
}
class dog extends Animal{
constructor(name:string){
super(name);
}
say(){
console.log(this.name+" wang wang");
}
}
const a= new Animal("tiger");
a.run(10);
const d = new dog("旺财");
d.run(5)
d.say();
//多态 父类型的引用指向子类对象
//不能调用子类特有的方法
let c:Animal = new dog("xiaoming")
c.run(8)
//权限修饰符 readonly只读
/*
访问修饰符: 用来描述类内部的属性/方法的可访问性
public: 默认值, 公开的外部也可以访问
private: 只能类内部可以访问
protected: 类内部和子类可以访问
readonly只读修饰构造器参数,那么类中就有了此属性
*/
class stuudent{
public name:string
readonly age:number
protected address:string
private num:number
constructor(name:string){
this.name=name
}
}
//存取器 get set 方法
class Person2 {
firstName: string = 'A'
lastName: string = 'B'
get fullName () {
return this.firstName + '-' + this.lastName
}
set fullName (value) {
const names = value.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
}
//静态成员
class country{
static na:string="中国"
static sayHello(){
console.log("welcome to "+country.na)
}
}
console.log(country.na)
country.sayHello()
//抽象类 定义抽象类和在抽象类内部定义抽象方法。
abstract class Animal1 {
abstract cry ()
run () {
console.log('run()')
}
}
class Dog1 extends Animal1 {
cry () {
console.log(' Dog cry()')
}
}
const dogg = new Dog1()
dogg.cry()
dogg.run()
})()
4、函数
(()=>{
//命名函数
function add(x,y){
return x*y
}
console.log(add(2,5))
//匿名函数
let add2 = function(x:number,y:number){
return x+y
}
console.log(add2(5,3))
//完整函数类型
let add3:(x:number,y:number)=>number = function(x:number,y:number):number{
return x-y
}
console.log(add3(9,4))
//默认参数 可选参数?
function getFullName(first:string="bob",last?:string){
if(last){
return first+"_"+last
}
return first
}
console.log(getFullName())
console.log(getFullName("alicr","good"))
//剩余参数
function info(x: string, ...args: string[]) {
console.log(x, args)
}
info('abc', 'c', 'b', 'a')
//函数重载 函数名相同, 而形参不同的多个函数
// 重载函数声明
function add25 (x: string, y: string): string
function add25(x: number, y: number): number
// 定义函数实现
function add25(x: string | number, y: string | number): string | number {
// 在实现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个 x + y
if (typeof x === 'string' && typeof y === 'string') {
return x + y
} else if (typeof x === 'number' && typeof y === 'number') {
return x + y
}
}
console.log(add25(1, 2))
console.log(add25('a', 'b'))
})()
5、泛型
(()=>{
//泛型 指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。
function get10<T>(s:T){
return s +" good good study"
}
console.log(get10(10))
console.log(get10("JACK"))
//多个泛型参数的函数
function swap <K, V> (a: K, b: V): [K, V] {
return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())
//泛型接口
interface IbaseCRUD <T> {
data: T[]
add: (t: T) => void
getById: (id: number) => T
}
class User {
id?: number; //id主键自增
name: string; //姓名
age: number; //年龄
constructor (name, age) {
this.name = name
this.age = age
}
}
class UserCRUD implements IbaseCRUD <User> {
data: User[] = []
add(user: User): void {
user = {...user, id: Date.now()}
this.data.push(user)
console.log('保存user', user.id)
}
getById(id: number): User {
return this.data.find(item => item.id===id)
}
}
const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)
//泛型类 在定义类时, 为类中的属性或方法定义泛型类型 在创建类的实例时, 再指定特定的泛型类型
class GenericNumber<T> {
zeroValue: T
add: (x: T, y: T) => T
}
let myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 0
myGenericNumber.add = function(x, y) {
return x + y
}
let myGenericString = new GenericNumber<string>()
myGenericString.zeroValue = 'abc'
myGenericString.add = function(x, y) {
return x + y
}
console.log(myGenericString.add(myGenericString.zeroValue, 'test'))
console.log(myGenericNumber.add(myGenericNumber.zeroValue, 12))
//泛型约束
interface Lengthwise {
length: number;
}
// 指定泛型约束
function fn2 <T extends Lengthwise>(x: T): void {
console.log(x.length)
}
})()
6、其他
6.1声明文件
/*
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
声明语句: 如果需要ts对新的语法进行检查, 需要要加载了对应的类型说明代码
declare var jQuery: (selector: string) => any;
声明文件: 把声明语句放到一个单独的文件(jQuery.d.ts)中, ts会自动解析到项目中所有声明文件
下载声明文件: npm install @types/jquery --save-dev
*/
jQuery('#foo');
// ERROR: Cannot find name 'jQuery'.
6.2 内置对象
ECMAScript 的内置对象
Boolean
Number
String
Date
RegExp
Error
/* 1. ECMAScript 的内置对象 */
let b: Boolean = new Boolean(1)
let n: Number = new Number(true)
let s: String = new String('abc')
let d: Date = new Date()
let r: RegExp = /^1/
let e: Error = new Error('error message')
b = true
// let bb: boolean = new Boolean(2) // error
BOM 和 DOM 的内置对象
Window
Document
HTMLElement
DocumentFragment
Event
NodeList
const div: HTMLElement = document.getElementById('test')
const divs: NodeList = document.querySelectorAll('div')
document.addEventListener('click', (event: MouseEvent) => {
console.dir(event.target)
})
const fragment: DocumentFragment = document.createDocumentFragment()