一:变量类型
数字类型(number)
let num: number = 1;
let num2: number = 0.8;
let num3: number = Infinity; // 整无穷大
let num4: number = -Infinity; // 负无穷大
let num5: number = NaN; // 属于Number类型空值(void)
表示没有任何返回值的函数
function alertMyName(): void {
alet('my name is david');
}声明一个void的类型变量没有声明用,只能将它赋值为undefined和null;
let unuseable: void = undefined;Null 和 Undefine
let n: undefined = undefined;
let u: null = null;与void的区别是,null和undefined是所有类型的子类型。也就是说undefined类型的变量,可以赋值给number类型的变量,如下:
let num: number = undefined; // 这样是不会报错的// 这样也不会报错
let u: undefined;
let num: number = u;而void类型的变量不能赋值给number类型的变量:
let u: void;
let num: number = u;
// Type 'void' is not assignable to type 'number'.字符串(string)
let myName: string = 'david';
let myAge: number = 26;
//模板字符串
let sentence: string = `Hello, my name is ${myName}.I'll be ${myAge + 1} years old next month`;布尔值(Boolean)
let isDone: boolean = false;注意,使用构造函数Boolean创造的对象不是布尔值
let createNewBoolean: boolean = new Boolean(1);
// Type 'Boolean' is not assignable to type 'boolean'.事实上new Boolean() 返回的是一个 Boolean 对象:
let createyNewBoolean: Boolean = new Boolean(1);直接调用Boolean也可以返回一个boolean类型:
let createBoolean: boolean = Boolean(1);在typescript中,boolean是JavaScript中的基本类型,而Boolean是JavaScript中的构造函数。
数组类型
最简单的方法是使用「类型 + 方括号」来表示数组:
let numArr: number[] = [1, 2, 3, 4];数组的项中不允许出现其他类型:
let arr: number[] = [1, '', 2, 3, 4];
// Type 'string' is not assignable to type 'number'.数组的一些方法也会根据数组在定义时约定的类型限制,比如:
let nums: number[] = [1, 2, 3, 4, 5];
nums.push('6');
// Argument of type '"6"' is not assignable to parameter of type 'number'.
//'6'是字符串类型数组泛型
let arr: Array<number> = [1, 2, 3, 4, 5];
let str: Array<string> = ['a', 'b', 'c'];元祖类型
数组是合并了相同类型的对象,而元祖合并了 不同类型的对象。
定义一对值分别为string和number的元祖:
let score: [string, number] = ['david', 26];当赋值或访问一个已知索引的元素时,会得到正确的类型:
let david:[string, number];
david[0] = 'david';
david[1] = 26;
david[0].slice(1);
david[1].toFixed(2);当然也可以只赋值其中一项:
let david: [string, number];
david[0] = 'david';但是直接对元祖类型的变量进行初始化或者赋值的时候,没需要提供所有元祖类型中指定的项。
let david: [string, number];
david = ['david', 26];let david: [string, number];
david = ['david'];
/ Property '1' is missing in type '[string]' but required in type '[string, number]'.枚举类型
枚举成员会被赋值为从0开始递增的数字,同时也会对枚举值到枚举名进行反向映射:
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true
console.log(Days[0] === "Sun"); // trueconsole.log(Days[1] === "Mon"); // trueconsole.log(Days[2] === "Tue"); // trueconsole.log(Days[6] === "Sat"); // true手动赋值
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true在上面的例子中未手动赋值的枚举项会接着上一个枚举项递增。
如果未手动赋值的枚举项与手动赋值的重复了,TypeScript是不会察觉到这一点的:
enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 3); // trueconsole.log(Days["Wed"] === 3); // trueconsole.log(Days[3] === "Sun"); // falseconsole.log(Days[3] === "Wed"); // true上面编译后的结果是:
var Days;(function (Days) { Days[Days["Sun"] = 3] = "Sun"; Days[Days["Mon"] = 1] = "Mon"; Days[Days["Tue"] = 2] = "Tue"; Days[Days["Wed"] = 3] = "Wed"; Days[Days["Thu"] = 4] = "Thu"; Days[Days["Fri"] = 5] = "Fri"; Days[Days["Sat"] = 6] = "Sat";})(Days || (Days = {}));所以平时我们在写的时候,尽量注意不要出现覆盖的现象;
如果手动赋值的项不是数字,此时需要使用类型断言来让tsc无视类型检查(编译出的js仍然是可用的):
enum Days {Sun = 7, Mon, Tue, Wed, Thu, Fri, Sat = <any>"S"};var Days;(function (Days) { Days[Days["Sun"] = 7] = "Sun"; Days[Days["Mon"] = 8] = "Mon"; Days[Days["Tue"] = 9] = "Tue"; Days[Days["Wed"] = 10] = "Wed"; Days[Days["Thu"] = 11] = "Thu"; Days[Days["Fri"] = 12] = "Fri"; Days[Days["Sat"] = "S"] = "Sat";})(Days || (Days = {}));当赋值的枚举项为小数或负数时,此时后续未手动赋值的项的递增步长仍未1:
enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1.5); // trueconsole.log(Days["Tue"] === 2.5); // trueconsole.log(Days["Sat"] === 6.5); // true任意值
任意值(Any)是用来允许赋值为任意类型。
如果是一个普通类型,在赋值过程中改变类型是不被允许的:
let num: number = 5;
num = 'five';
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.如果是any类型:
let num: any = 'five';
num = 5;接口(interface )
除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
interface Person {
name: string;
age: number;
}
let david: Person = {
name: 'david',
age: 26
};定义的变量比接口少了一些属性是不被允许的:
interface Person {
name: string;
age: number;
}
let david: Person = {
name: 'david'
};
// index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.// Property 'age' is missing in type '{ name: string; }'.多一些属性也是不被允许的:
interface Person {
name: string;
age: number;
}
let david: Person = {
name: 'david',
age: 26,
gender: 'male'
};
// index.ts(9,5): error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.// Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.由此可见,赋值的时候,变量的形状必须和接口的形状保持一致。
可选属性
有时我们希望不要完全匹配一个形状,那么可以用可选属性:
interface Person {
name: string;
age?: number;
};
let devid: Person = {
name: 'david'
}
// 或者
let devid: Person = {
name: 'david',
age: 26
}可选属性的含义是该属性可以不存在。