简而言之,TypeScript是JavaScript的超集,具有可选的类型并可以编译为纯JavaScript。从技术上讲TypeScript就是具有静态类型的 JavaScript 。
什么是 TypeScript?
- TypeScript 是添加了类型系统的 JavaScript,适用于任何规模的项目。
- TypeScript 是一门静态类型、弱类型的语言。
- TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性。
- TypeScript 可以编译为 JavaScript,然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。
- TypeScript 拥有很多编译选项,类型检查的严格程度由你决定。
- TypeScript 可以和 JavaScript 共存,这意味着 JavaScript 项目能够渐进式的迁移到 TypeScript。
- TypeScript 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
- TypeScript 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
- TypeScript 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。
类型系统
-
类型系统按照「类型检查的时机」来分类,可以分为动态类型和静态类型。
动态类型:是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。
静态类型:是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。 -
类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型。
这样的类型系统体现了 TypeScript 的核心设计理念:在完整保留 JavaScript 运行时行为的基础上,通过引入静态类型系统来提高代码的可维护性,减少可能出现的 bug。
类型推论
如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
let name = 'hh'
name = 1;
// error TS2322: Type 'number' is not assignable to type 'string'.
TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any
类型而完全不被类型检查:
let name;
name = 1;
name = 'hh'
TypeScript 中的数据类型
- 布尔类型(boolean)
let b: bolean = true;
- 数字类型(number)
let n: number = 1;
- 字符串类型(string)
let str: string = 'holle';
- 数组类型(array)
类型 + 方括号」表示法
let arrNum1: number[] = [1, 2, 3];
let arrStr1: string[] = ['name', 'age', 'sex'];
let arr1: any[] = ['name',1,true];
数组泛型
let arrNum2: Array<number> = [1, 2, 3];
let arrStr2: Array<string> = ['name', 'age', 'sex'];
let arr2: Array<any> = ['name',1,true];
用接口表示数组
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
虽然接口也可以用来描述数组,但是我们一般不会这么做,因为这种方式比前两种方式复杂多了。
不过有一种情况例外,那就是它常用来表示类数组。
- 元组类型(tuple)
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同
let arr:[string, number, boolean] = ['name', 1, true];
-
枚举类型(enum)
枚举类型用于定义数值集合,使用枚举我们可以定义一些带名字的常量。 使用枚举可以清晰地表达意图或创建一组有区别的用例,例如 一年十二个月
-
普通枚举
初始值默认为 0 其余的成员会会按顺序自动增长 可以理解为数组下标enum Color {red, green, blue}; let c: Color = Color.green; console.log(c); // 1
-
设置初始值
enum Color {red = 1, green = 2, blue = 3}; let c: Color = Color.green; console.log(c); // 2
-
字符串枚举
enum Color { RED = "红色", PINK = "粉色", BLUE = "蓝色", } const pink: Color = Color.PINK; console.log(pink); // 粉色
-
常量枚举
-
-
任意类型(any)
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
any
类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。你可能认为 Object
有相似的作用,就像它在其它语言中那样。 但是 Object
类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法,即便它真的有这些方法
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
- null 和 undefined
let u: undefined = undefined;
let n: null = null
- void 类型
当一个函数没有返回值时,通常会使用
function test():void{
console.log('test');
}
- never类型
类型表示的是那些永不存在的值的类型
-
函数类型
一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:
-
函数声明
function sum(x: number, y: number): number { return x + y; }
-
函数表达式
let mySum = function (x: number, y: number): number { return x + y; };
这是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的
mySum
,是通过赋值操作进行类型推论而推断出来的。如果需要我们手动给mySum
添加类型,则应该是这样:let mySum: (x: number, y: number) => number = function (x: number, y: number): number { return x + y; };
注意不要混淆了 TypeScript 中的
=>
和 ES6 中的=>
。在 TypeScript 的类型定义中,
=>
用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。 -
用接口定义函数的形状
interface SearchFunc { (source: string, subString: string): boolean; } let mySearch: SearchFunc; mySearch = function(source: string, subString: string) { return source.search(subString) !== -1; }
-
重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
function reverse(x: number | string): number | string | void { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } }
然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串
function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string | void { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } }
TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
-
联合类型
联合类型(Union Types)表示取值可以为多种类型中的一种。
联合类型使用 |
分隔每个类型。
let name: string | number;
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
接口
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。
在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。
TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
-
可选属性
好处之一是可以对可能存在的属性进行预定义,
好处之二是可以捕获引用了不存在的属性时的错误。interface Person { name: string; age: number; } let tom: Person = { name: 'Tom', age: 25 };
-
任意属性
有时候我们希望一个接口允许有任意的属性,可以使用如下方式:
interface Person { name: string; age?: number; [propName: string]: any; } let tom: Person = { name: 'Tom', gender: 'male' };
使用
[propName: string]
定义了任意属性取string
类型的值。需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:interface Person { name: string; age?: number; [propName: string]: string; } let tom: Person = { name: 'Tom', age: 25, gender: 'male' }; // index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'. // index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'. // Index signatures are incompatible. // Type 'string | number' is not assignable to type 'string'. // Type 'number' is not assignable to type 'string'.
上例中,任意属性的值允许是
string
,但是可选属性age
的值却是number
,number
不是string
的子属性,所以报错了。另外,在报错信息中可以看出,此时 { name: 'Tom', age: 25, gender: 'male' } 的类型被推断成了 { [x: string]: string | number; name: string; age: number; gender: string; },这是联合类型和接口的结合。
-
只读属性
属性名前用
readonly
来指定只读属性interface Point { readonly x: number; readonly y: number; } let coordinate:Point ={ x: 1, y: 1 } coordinate.x = 1; // error TS2540: Cannot assign to 'x' because it is a read-only property.
注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候:
类型断言
需要注意的是,类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误,反而滥用类型断言可能会导致运行时错误
as <类型>
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
- 泛型约束
function loggingIdentity<T>(arg: T): T {
console.log(arg.length);
return arg;
}
// index.ts(2,19): error TS2339: Property 'length' does not exist on type 'T'.
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
标签:typeScript,string,number,笔记,学习,TypeScript,let,类型,name From: https://www.cnblogs.com/zshno1/p/17172987.html