TypeScript 是微软开发的一个开源的编程语言,通过在 JavaScript的基础上添加静态类型定义构建而成。TypeScript通过 TypeScript编译器或 Babel 转译为 JavaScript代码,可运行在任何浏览器,任何操作系统。TypeScript 是 JavaScript 的超集
超集 : 如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S1就是S2的一个超集,反过来,S2是S1的子集。 S1是S2的超集,若S1中一定有S2中没有的元素,则S1是S2的真超集,反过来S2是S1的真子集。 例如 :sass是 css的超集 C++是 C 语言的超集
安装 TypeScript 之间需要安装 node 环境
有时间写一个 详细的过程配置
当版本号显示正常说明安装成功
终端:
npm install typescript -g // 安装TypeScript
tsc --version // 查看版本号
npm init -y // 项目初始化
tsc --init // 生成 tsconfig.json 文件
tsconfig.json 将 ts 转换为 js 的一个配置文件
npm install @types/node --dev-save
该依赖是在开发环境中解决模块声明文件问题
// TypeScript 支持强类型,所以我们声明一个变量a可以给它加上类型
var a:string = "HelloWorld"
console.log(a)
要运行 TypeScript 需要转换为 JavaScript
点击终端 ----- 点击运行任务 ----- 选择 tsc 监视
使用 tsc 加文件名可以运行 ts 文件 然后生成 js 文件
有了 js 文件,我们就可以在终端使用node来运行它了
TypeScript 中的数据类型有Undefined、Number(数值类型)、string(字符串类型)、Boolean(布尔类型)、enum(枚举类型)、any(任意类型)、void(空类型)、Array(数组类型)、Tuple(元祖类型)、Null(空类型)。
TypeScript 相对于 JavaScript 增加了新的数据类型,这些数据类型只用于 TypeScript 环境下,当TypeScript 编译成 JavaScript 的时候,会去掉 TypeScript 中的新类型 转变成 JavaScript 中的数据类型。
当定义了一个变量,没有给这个变量进行赋值,那这个变量中有一个默认值 undefined,undefined 就是 Undefined 类型。
let a: number;
console.log(a); //输出undefined
和JavaScript一样,TypeScript里的所有数字都是浮点数。 这些浮点数的类型是 number。
let b: number = 10; // 整数
let c: number = 2.13 // 浮点数
在 TypeScript 中存在以下几种特殊的 Number 类型数据:
由单引号’'或者双引号""括起来的一串字符就是字符串。
let d: string = "lanbots"; //输出 lanbots
let e: string = 'linbots'; //输出 linbots
你还可以使用模版字符串,它可以定义多行文本和内嵌表达式。 这种字符串是被``
包围 ,并且以${ expr }
这种形式嵌入表达式
let name: string = "lanbots";
let age: number = 23;
let sentence: string = `my name is ${ name }.
I'll be ${ age + 1 } years old next month.`;
这与下面定义sentence的方式效果相同:
let sentence: string = "my name is " + name + ".\n" +
"I'll be " + (age + 1) + " years old next month.";
在程序中我们经常碰到这样的情况:判断条件是否成立,判断对错。这样的结果无非就是两种情况:是,否。表示这种情况的变量就是布尔类型(boolean),其数值有 true 和 false。
let a: boolean = false; // Boolean类型,编译通过
let b: boolean = 0; // Boolean类型,使用数字赋值,编译失败
当出现以下这种情况:
这种变量的结果可能是固定的几种数据,我们使用枚举类型表示。
//表示四季这种情况 定义一个枚举类型的变量 定义枚举的关键字是enum
//一般枚举类型的变量 用大写字母表示
enum SEASON{
SPR,//结果一般也用大写字母表示
SUM,//结果之间用逗号隔开
AUT,
WIN
}
console.log(SEASON.SPR);//0
enum CUP_TYPE{
//在ts中会给每一个可能的结果赋值一个整数 方便在计算机中存储和使用 默认是0
SMALL_CBIG_CUP_TYPE = 1,
MID_CUP_TYPE,//2
BIG_CUP_TYPE // 3
}
console.log( CUP_TYPE.MID_CUP_TYPE);
如果我们要打印出来内容,应该怎么操作呢?
enum SEASON{
SPR="春",
SUM="夏",
AUT="秋",
WIN="冬"
}
console.log(SEASON.SPR);//春
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any
类型来标记这些变量:
let a: any;
a = 23;
a = "lanbots";//a可以再次赋值任意类型的值
console.log(a); //输出lanbots
某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:
function warnUser(): void {
alert("This is my warning message");
}
声明一个void
类型的变量没有什么大用,因为你只能为它赋予undefined和null
let unusable: void = undefined;
never
类型表示的是那些永不存在的值的类型。 例如, never
类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never
类型,当它们被永不为真的类型保护所约束时。
never
类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never
的子类型或可以赋值给never类型(除了never
本身之外)。 即使 any
也不可以赋值给never
。
类型断言(Type Assertion)可以用来手动指定一个值的类型
有的时候在联合类型的时候,只能访问联合类型的共有方法或者属性,但是这个时候是不够用的。这个时候就要自己手动断言成某个类型。断言不是改变某个类型,不是类型转换。这个时候能让取到你断言成的类型的方法。
类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的
function getLength(something: string | number): number {
if (something.length) {
return something.length;
} else {
return something.toString().length;
}
}
// index.ts(2,19): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.
// index.ts(3,26): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.
上例中,获取 something.length 的时候会报错。
此时可以使用类型断言,将 something 断言成 string:
function getLength(something: string | number): number {
if ((<string>something).length) {
return (<string>something).length;
} else {
return something.toString().length;
}
}
类型断言有两种形式。 其一是“尖括号”语法:
let someValue: any = "this is a string";
<类型>值
let strLength: number = (<string>someValue).length;
另一个为as语法:
let someValue: any = "this is a string";
值 as 类型
let strLength: number = (someValue as string).length;
两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。
功能相近、多次使用,根据参数呈现不同结果的独立代码块
function searchXiaoJieJie(age:number):string {
return '找到了'+age +'岁的小姐姐'
}
var age:number = 18;
var result:string=searchXiaoJieJie(age)
console.log(result) // 找到了18岁小姐姐
注意
function
这个关键字来定义一个函数function searchXiaoJie Jie(age:number,status?:string):string {
let yy:string=''
yy='找到了'+age+'岁'
if(status!=undefined){
yy = yy +status
}
return yy+'的小姐姐'
}
var result:string=searchXiaoJieJie(22,'大长腿')
console.log(result)
function searchXiaoJieJie(age:number=18,status:string='小蛮腰'):string {
let yy:string=''
yy='找到了'+age+'岁'
if(status!=undefined){
yy = yy +status
}
return yy+'的小姐姐'
}
var result:string=searchXiaoJieJie()
console.log(result) //找到了18岁小蛮腰的小姐姐(不传参)
var result:string=searchXiaoJieJie(22,'大长腿')
console.log(result) //找到了22岁大长腿的小姐姐(传参)
function searchXiaoJieJie(...xuqiu:string[]):string {
let yy:string='找到了'
for(let i=0;i<xuqiu.length-1;i++) {
yy = yy +xuqiu[i]
if(i<xuqiu.length){
yy = yy + '、'
}
}
yy=yy+'的小姐姐'
return yy
}
var result:string=searchXiaoJieJie('22岁','大长腿','瓜子脸','小蛮腰')
console.log(result) // 找到了22岁、大长腿、瓜子脸、的小姐姐
+函数声明法(常用)
function add(n1:number,n2:number):number{
return n1+n2
}
console.log(add(1,2))
先声明一个变量,直接把这个函数赋值给变量,那么这个变量就是函数名,通过变量名可以调用这个函数
注意:定义之后要调用,否则会报错
var add = function(n1:num ber,n 2:number):number{
return n1+n2
}
console.log(add(1,3))
利于回调,函数都有作用域
var add=(n1:number,n2:number):number=>{
return n1+n2 //this
}
console.log(add(3,5)
利用TypeScript的关键词module
,可以达到类似于命名空间的效果,而export可以控制是否被外部访问。
// 通过class创建类
class Animal {
// 类的属性
name: string;
// 类的构造器
constructor(name: string) {
this.name = name;
}
// 类的方法
sayHello():void{
alert("hello animal:"+this.name);
}
}
// 实例化类
var tom = new Animal("tom");
tom.sayHello();
// 通过class创建类
class Animal {
// 类的属性
name: string;
// 类的构造器
constructor(name: string) {
this.name = name;
}
// 类的方法
sayHello(): void {
alert("hello animal:" + this.name);
}
}
// 继承Animal
class Cat extends Animal {
// 重写方法
sayHello(): void {
alert("hello cat:" + this.name);
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name);
}
}
class Animal {
private name: string; // 这里把name修饰符改为private
constructor(name: string) {
this.name = name;
}
sayHello(): void {
alert("hello animal:" + this.name);
}
}
class Cat extends Animal {
sayHello(): void {
alert("hello cat:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
}
}
当把属性的修饰符改成私有时,子类继承以后便会报错。那么如何解决呢?看下一节。
class Animal {
private name: string;
get name(): string { //通过get和set解决子类不能引用父类private修饰的属性的问题
return this.name;
}
set name(name: string) {
this.name = name;
}
constructor(name: string) {
this.name = name;
}
sayHello(): void {
alert("hello animal:" + this.name);
}
}
class Cat extends Animal {
sayHello(): void {
alert("hello cat:" + this.name);
}
}
class Dog extends Animal {
sayHello(): void {
alert("hello dog:" + this.name);
}
}
class Table {
static width: Number = 100;
static height: Number = 50
}
var width: Number = Table.width;