TS 入门
1. 准备工作a. 安装node (在Windows上安装时务必选择全部组件,包括勾选Add to Path。)node -v (检查node版本及是否安装成功)b. 全局安装ts (安装之后可用命令: tsc 运行ts文件)yarn add global typescript (或者 npm install -g typescript )用 yarn 安装之前...
目录
一、 准备工作
a. 安装node (在Windows上安装时务必选择全部组件,包括勾选Add to Path
。)
node -v (检查node版本及是否安装成功)
b. 全局安装ts (安装之后可用命令: tsc 运行ts文件)
yarn add global typescript (或者 npm install -g typescript )
用 yarn 安装之前需安装yarn 相关介绍看上参考之前的文章,这里是跳转链接
二、 创建 ts 项目文件并运行
a. 创建 ts 项目的专门目录, 建立index.ts文件(兼容js语法)
b. 命令行运行ts文件: tsc index.ts (会发现文件夹下会生成同名js文件)
c. 命令行运行js文件:node index.js (可以省略后缀,上同)
d. 添加 tsconfig.json文件命令 : tsc --init (告诉编译器以什么标准解析ts)
e. 点击终端-->运行生成任务--> tsc:监视 (可以监控ts文件改动后自动编译生成对应js文件)
三、 五分钟上手 ts
可参考这篇文章
index.ts 示例文件如下:
interface Person {
firstName: string;
lastName: string;
}
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
console.log(document.body.innerHTML);
四、 ts 相关要点
以下做简要介绍, 需要了解具体内容可自行查阅官网文档
基本数据类型
// ts 是 js 的超集:兼容js语法并加以扩展
console.log('hello,ts');
// 基本数据类型
// 字符串 数字 undefined null 布尔值
var a : string= 'str'
a = 'string'
let num : number = 2
num = 3
// undefined:js中声明但未赋值时结果;取对象上不存在的属性
let un:undefined = undefined
let nu:null = null
let isDone: boolean = false;
console.log(a,num,un,nu,isDone);
非基本数据类型
// 数组
// var arr:Array = [1] // 不推荐(声明时必须传值)
var arr:[]=[] // 表明arr 只能是空数组 下面俩行可 但不能push(1)
arr.length
arr.push()
var ids:number[]= [] // 表明arr 只能是承载number元素的数组
ids.push(33)
console.log(ids);
// 元组(规定长度、类型的数组)
let typeArr:[string, number]
typeArr = ['xiaowang',18]
// typeArr = ['xiaowang',18,‘小仙女’] //报错 长度超出了
// 枚举(ts新增类型) ==> 生成一个相互引用的对象(键值互相可拿到对方)
enum types {
typestring, // 默认索引从0开始
typenumber, // 索引为1
typenull = 21,
typeundefined // 索引为22
}
console.log(types);
// 使用场景:后台返回状态码,前台自动显示对应提示信息,无需if/switch判断
enum msgs{
'成功' = 200,
'账号错误' = 301,
'密码错误' = 402
}
console.log(msgs);
// any 任意类型 (少用)
var type : any
type = 'xxx'
type = 9
type = []
type = true
console.log(type);
// void ==> 没有值
// 使用场景:规范一个函数没有返回值
let vts :void
// vts = void // 只能设置成void或undefined
vts = undefined
// Function
var fun : Function = ()=>{}
fun = function(){console.log(1);}
var fun2 = function(){console.log(2);
}
接口与类型
不同点:
类型别名 type 不仅可以用来表示基本类型,还可以用来表示对象类型;接口interface
仅限于描述对象类型。
interface使用“extends”扩展,type使用“&”继承 。
相同点:
interface
和 type
都可以继承。
接口与继承
// 接口(限制对象)
// 定义接口
interface info{
username : string,
id : number,
vip ?: boolean // 可选 布尔型
readonly age : number, // readonly: 规定属性 只读不可更改
// const: 规定变量不可变
sayhi() : void,
// 给接口留有余地
[props:string]:any // 可选 任意(字符串类型)属性名且属性值(可为任意类型)
}
// 使用接口 必须包含以上必选属性 且类型对应;不能添加未定义的属性
var obj : info = {
username: 'wb',
id : 1,
vip : true,
age :16,
sayhi : ()=>{console.log('嗨');
}
}
obj.id = 2
obj.vip = false
obj.prop1 = '1' // 符合接口中的定义: [props:string]:any
obj.prop2 = 2 // 同上
console.log(obj);
obj.sayhi()
// 限制函数
// 定义
interface sayhiInt{
(str:string):string //限定:参数类型 返回值
}
// 使用
var sayhi : sayhiInt = function(s:string){
return '你好' + s
}
console.log(sayhi('wb') );
// 接口继承
// 定义vip
interface vipInt{
isvip : boolean,
vipType : number
}
// 定义 info
interface infoInt{
username : string,
id : number,
vip ?: boolean // 可选 布尔型
readonly age : number, // 规定属性 只读
// const 规定变量不可变
sayhi() : void,
// 给接口留有余地
// 可选属性名(字符串类型)属性值(任意)
[propsName:string]:any
}
// 定义 函数接口
interface sayhiInt {
(str:string): string
}
// 继承以上俩个接口
interface vipinfoInt extends vipInt,infoInt{
isadd : boolean
}
// 使用
let vipinfoData : vipinfoInt = {
isvip : true,
vipType : 3 ,
username : 'ww',
id : 2,
age :19,
sayhi:()=>{console.log('hi') },
isadd : true
}
console.log( vipinfoData );
// 混合类型 : 规范函数
interface icontInt{
count : number, // 元素属性
() : void // 函数属性
}
// 声明一个函数满足 icontInt的约束:需包含其中属性
let getcount = function():icontInt{
let countFun = <icontInt> function(){
countFun.count++
console.log(countFun.count);
}
countFun.count = 1
return countFun
}
console.log( getcount() );
类及继承
// 类的定义
class Info {
userName: string
id: number
type: string
age: number = 18
// 构造函数
constructor(u: string, i: number, t: string) {
this.userName = u
this.id = i
this.type = t
}
}
// 实例化对象
var Minfo = new Info('wb', 1, 'vip')
console.log(Minfo);
class Sayhi {
hiFun() {
console.log('你好');
}
}
var hi = new Sayhi()
console.log(hi);
类的继承:
a. 子类从基类中继承(extends)属性和方法,可以重写父类,也能写自身的属性
b. 子类若有构造函数,必须调用 super(),会执行基类的构造函数。且在构造函数里访问 this的属性之前,要调用 super()
c. 类可以创建出类型,与接口有类似之处,所以允许在使用接口的地方使用类
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
函数
函数类型:参数类型与返回值类型约束,可以规定形参和返回值的类型,如果函数没有返回任何值,必须指定返回值类型为void而不能留空。
let myAdd: (x: number, y: number) => number =
function(x: number, y: number): number { return x + y; };
可选参数 lastName?: string 只能跟在必须参数后面 不传的话值为undefined :
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
let result1 = buildName("Bob"); // works correctly now
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result3 = buildName("Bob", "Adams"); // ah, just right
剩余参数 ...restOfName: string[] 收集到一个数组里:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
// 省略号也会在带有剩余参数的函数类型定义上使用到:
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
泛型
定义:根据形参推断出返回的类型,内部也只使用该类型的方法,注意规范避免某类型的方法。以下以泛型函数为例,也可有泛型类。
function identity<T>(arg: T): T {
return arg;
}
// 给identity添加了类型变量T,T帮助捕获传入的类型(比如:number)
// 再次使用了 T 当做返回值类型,即参数类型与返回值类型是相同的
泛型接口T:T用于泛型数据类型的约束 ,也可以约束类(构造函数);相当于形参的一部分 表示的是实际参数的类型。
泛型变量:
function loggingIdentity<T>(arg: T): T {
console.log(arg.length); // Error: T doesn't have .length
return arg;
}
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
泛型继承: 用于扩展类型 (定义一个接口 :包含 length属性,让一个泛型继承该接口 就有了length属性)
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
类型兼容:
1. 属性 ‘多的’ 对象能赋值给 ‘少的’ ,反之不行
interface Named {
name: string;
}
let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: 'Alice', location: 'Seattle' };
x = y; // ok
y = x; // Error
2.参数 ‘少的’ 能赋值给参数 ‘多的’
let x = () => ({name: 'Alice'});
let y = () => ({name: 'Alice', location: 'Seattle'});
x = y; // OK
y = x; // Error, because x() lacks a location property
高级类型:
1. 交叉类型:& 将多个类型合并为一个类型
2. 联合类型:| 表示一个值可以是几种类型之一
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
let indentedString = padLeft("Hello world", true); // errors during compilation
注意:如果一个值是联合类型,我们只能访问此联合类型的所有类型里共有的成员。
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// ...
}
let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim(); // errors, 不能确定一个 Bird | Fish 类型的变量是否有 fly方法
介于篇幅有限,对于 ts 剩余的内容,诸如:
类型断言: as 用某个属性时,先断言该属性的对象存在
命名空间namespace :空间内的变量要在外面使用 须export
/// :使用多个 /// <reference path="..." /> 把不同文件地址里的命名空间合并处理
装饰器
声明文件: .d.ts (declare)
等下次更新......
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)