概述
TypeScript是JavaScript的超集,提供了更严格的类型声明,方便在静态类型检查时就避免因为类型问题产生的bug。
工欲善其事,必先利其器,让我们来看看TypeScript是怎样声明数据类型的
一. 声明
1. 基本数据类型+ts特有类型void声明
/**
* Note: 未指定类型时, TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型
* 如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查
* let a = 7
* a = 'seven' // Error:不能将类型“"seven"”分配给类型“number”
*/
const num:number = 123
const str:string = '123'
const bool:boolean = true
const und:undefined = undefined
const nu: null = null
let u: void;
console.log(num,str,bool,und,nu, u) // 123 '123' true undefined null undefined
2. 任意值类型
let everyOne: any = 'seven';
console.log(everyOne)
everyOne = 7
console.log(everyOne)
console.log(everyOne.name)
3. 联合类型,表示取值可以为多种类型中的一种
// 用|表示联合
let test: string | number;
4. 对象类型-接口
/**
* Note: 定义的变量不允许比接口属性少或多,形状必须和接口一致
* 如果希望不完全匹配,可使用可选属性(该属性可以不存在,但仍不允许添加)
* interface Person {
* name: string;
* age?: number;
* }
*
* 要添加的话使用任意属性
* interface Person {
* name: string;
* age?: nuber;
* [propName: string]: any;
* }
* */
interface Person {
readonly id: number; // 只读属性
name: string;
age?: number; // 可选属性
[propName: string]: any; // 任意属性
}
t
let tom: Person = {
id: 123,
name: 'TOM',
age: 25,
gender: '女'
}
5. 数组类型
5.1 数组+方括号表示法
let fib:number[] = [1,2,3]
// let fib1:number[] = [1,2,3,'1'] // 不能将类型“string”分配给类型“number”
5.2 数组泛型
let fibonacci: Array<number> = [1, 1, 2, 3, 5];
5.3 接口表示
interface NumberArray {
[index: number]: number;
}
let fib1: NumberArray = [1,2,3]
6. 类数组
/**
* Note:
* 类数组不是数组类型,如arguments,dom queryselector
* 通常用接口表示,可以自定义接口,也可用TypeScript封装的接口
*/
interface IArguments {
[index: number]: any;
length: number;
callee: Function;
}
function sum() {
let args: IArguments = arguments
console.log(args)
}
let liList: HTMLCollection = document.getElementsByTagName('li')
7. 函数声明
7.1 函数对输入输出类型进行约束
function sum2(x: number, y: number): number {
return x + y;
}
7.2 函数表达式
/**
* Note:
* 下面表达式等号右边的为函数声明, 左边的是对mySum变量的约束
* 左边的=>与es6中的箭头函数意义不同,代表的是函数类型,箭头左边为输入类型,右边为输出类型
*/
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
7.3 接口定义函数
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
// 可选参数, 可选参数后面不允许再出现必需参数,可以跟默认参数
function buildName(name?: string, age: number = 0){
return name + age
}
// 剩余参数, rest参数只能是最后一个参数
function push(array, ...items: any[]){
items.forEach(function(item){
array.push(item);
})
}
// 函数重载,当函数体中有分支时,可能返回不同类型的值,可以使用重载
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
二. 声明文件
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能
声明文件必需以 .d.ts 为后缀
声明文件中下面命令代表含义:
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
export 导出变量
export namespace 导出(含有子属性的)对象
export default ES6 默认导出
export = commonjs 导出模块
export as namespace UMD 库声明全局变量
declare global 扩展全局变量
declare module 扩展模块
/// <reference /> 三斜线指令
1. 全局变量
declare var $: (selector: string) => any;
2. 全局函数
declare function jQuery(selector: string): any;
3. 声明全局类
declare class Animal {
name: string;
constructor(name: string);
sayHi(): string;
}
4. 枚举
declare enum Directions {
Up,
Down,
Left,
Right
}
5. 声明合并
// jQuery即是一个函数,又是一个对象,有自己的属性
declare function jQuery(selector: string): any;
declare namespace jQuery {
function ajax(url: string, settings?: any): void;
}
三. 进阶声明
类型别名与字符串字面量类型都是使用 type 进行定义
1. 类型别名
// 为string起个类型别名Name
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
// 声明时可用Name代表string类型
let name1: Name = '123'
console.log(name1) // 123
2. 字符串字面量
type EventNames = 'click' | 'scroll' | 'mousemove';
// 参数event的值必须为上面三个其中一个
function handleEvent(e: Element, event: EventNames){
// do something
}
3. 元组
let om: [string, number];
om[0] = 'Tom';
4. 枚举
4.1 普通枚举
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
4.2 常数枚举
常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员
const enum Directives {
Up, Down, Left, Right
}
4.3 外部枚举
常出现在声明文件中
declare enum Directions {
Up, Down, Left, Right
}
四. 类
1. TypeScirpt中类的用法
/**
* Note:
* public、private、protected(受保护的)
* 1. 使用private修饰的属性或方法,在子类也不允许访问
* 2. 使用protected修饰,在子类中允许访问
* 3. 当构造函数修饰为 private 时,该类不允许被继承或者实例化
* 4. 当构造函数修饰为 protected 时,该类只允许被继承
*/
class Animal {
protected name;
public constructor(name) {
this.name = name;
}
}
class Cat extends Animal {
constructor(name) {
super(name);
console.log(this.name);
}
}
2. 只读属性
readonly,只读属性关键字,只允许出现在属性声明或索引签名中
注意如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面
class Animal2 {
// public readonly name;
public constructor(public readonly name) {
this.name = name;
}
}
3. 抽象类
/**
* Note: abstract 用于定义抽象类和其中的抽象方法
* 抽象类不允许被实例化
* 抽象类中的抽象方法必须被子类实现
*/
abstract class Animal3 {
public name;
public constructor(name) {
this.name = name;
}
public abstract sayHi();
}
class Cat1 extends Animal3 {
public sayHi() {
console.log(`Meow, My name is ${this.name}`);
}
}
let cat = new Cat1('Tom');
五. 类与接口
1. 实现(implements)
可以将不同类之间共有的特性提取成接口(interface),用implements关键字实现
// 报警器接口
interface Alarm {
alert();
}
class Door {
}
// 安全门继承门的类 并实现报警器
class SecurityDoor extends Door implements Alarm {
alert() {
console.log('SecurityDoor alert');
}
}
2. 接口可以继承接口
interface B extends interfaceA {}
3. 接口继承类
interface B extends classA {}
六. 泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
1. 单个类型参数
// 使用T指代任意输入的类型, 输出则为Array<T>
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray<string>(3, 'x'); // ['x', 'x', 'x']
2. 多个类型参数
// 定义泛型的时候,可以一次定义多个类型参数
function swap<A, S>(tuple: [A, S]): [S, A] {
return [tuple[1], tuple[0]];
}
console.log(swap([7, 'seven']));
3. 泛型约束
// 比如让一个函数的参数和返回值必须拥有length方法时
interface Len {
length: number;
}
function lenFunc<T extends Len>(arg: T): T {
console.log(arg.length);
return arg
}
4. 使用泛型接口
// 使用含有泛型的接口来定义函数的形状
interface CreateArrayFunc {
<T>(length: number, value: T): Array<T>;
}
let createArray2: CreateArrayFunc;
createArray2 = function<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray2(3, 'x');
5. 泛型类
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; };
6. 为泛型指定默认类型
function con<T = string>(arg: T): T{
return arg
}
最后
以上就是缓慢跳跳糖为你收集整理的TypeScript语法规范的全部内容,希望文章能够帮你解决TypeScript语法规范所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复