TypeScript的基础类型包括: boolean、number、string、arr、元组 Tuple、undefined、null。
1、布尔值(boolean)
用boolean表示布尔类型,注意开头是小写,如果你在Typescript文件中写成 Boolean 那代表是 JavaScript 中的布尔对象
let idDone: boolean = false
// ES5:var isDone = false;
这里需要提示一下,很多 TypeScript 的原始类型比如 boolean、number、string等等,在JavaScript中都有类似的关键字 Boolean、Number、String,后者是 JavaScript 的构造函数,比如我们用 Number 用于数字类型转化或者构造 Number 对象用的,而 TypeScript 中的 number 类型仅仅是表示类型,两者完全不同。
2、数字(number)
TypeScript里的所有数字都是浮点数,支持二进制、八进制、十进制、十六进制等
let decLiteral: number = 6;
// ES6 中的十六进制表示法
let hexLiteral: number = 0xf00d;
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
let infinityNumber: number = Infinity;
编译成js后的结果是:
var decLiteral = 6;
// ES6 中的十六进制表示法
var hexLiteral = 0xf00d;
// ES6 中的二进制表示法
var binaryLiteral = 10;
// ES6 中的八进制表示法
var octalLiteral = 484;
var notANumber = NaN;
var infinityNumber = Infinity;
3、字符串(string)
我们使用string表示文本数据类型。 和JavaScript一样,可以使用双引号(")或单引号(')表示字符串。
let name: string = "bob";
// ES5:var name = "bob";
name = "smith";
还可以使用模版字符串,它可以定义多行文本和内嵌表达式。 这种字符串是被反引号包围(`),并且以${ expr }这种形式嵌入表达式
let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.
I'll be ${ age + 1 } years old next month.`;
这与下面定义sentence的方式效果相同:
let sentence: string = "Hello, my name is " + name + ".\n\n" +
"I'll be " + (age + 1) + " years old next month.";
4、数组([] /Array<元素类型>)
一般数组类型的定义两种定义数组的方式
4.1在元素后面接上[],表示由此类型元素组成的一个数组:
let list:number[] = [1,2,3];
// ES5:var list = [1,2,3];
如果你的数组各项组成是字符串,就可以这样写。
let stringStr:string[] = ["张三","李四","王五"];
也可以定义任意类型的数组,例如undefined。
let undefinedArr: undefined[] = [undefined, undefined];
这时候问题来了,如果数组中有多种类型,比如既有数字类型,又有字符串的时候。那我们要如何定义那。 很简单,只要加个(),然后在里边加上|就可以了,具体看代码。
let arr: (number | string | boolean)[] = [1, "string", 2, true];
\
4.2数组泛型,Array<元素类型>:
let list: Array<number> = [1,2,3];
// ES5:var list = [1,2,3];
字符串组成的数组就这样写
let stringStr: Array<String> = ["张三","李四","王五"];
undefined组成的数组这样写
let undefinedArr: Array<undefined> = [undefined, undefined];
多种类型组成的数组如下:
let arr: Array<number | string | boolean> = [1, "string", 2, true];
5、元组 Tuple
5.1元组类型
\
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。例如
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
5.2元组的使用
其实一般工作中我们不经常使用元组,如果要使用,可以用对象的形式来替换。有些老的数据源是csv,这种的文件提供的就是逗号隔开的,严谨编程就需要使用到元组了。
const person: [string, string, number][] = [ ["张三", "teacher", 28],
["李四", "teacher", 18],
["王五", "teacher", 25],
];
console.log(person);
编译运行就会得到如下结果:
6、枚举(enum)
enum类型是对JavaScript标准数据类型的一个补充。
enum Color{Red, Green, Blue}
let c:Color = Color.Green;
默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从1开始编号:
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
alert(colorName); // 显示'Green'因为上面代码里它的值是2
6.1数字枚举
下面我们来看看枚举应用的神奇之处
初级写法是这样的:
function studyCourse(course: number) {
if (course === 0) {
return "Typescript";
} else if (course === 1) {
return "javascript";
} else {
return "java";
}
}
const result = studyCourse(0);
console.log(`我要学习${result}`);
中级这样写:
const Course = {
ts: 0,
js: 1,
java: 2,
};
function studyCourse(course: any) {
if (course === Course.ts) {
return "Typescript";
} else if (course === Course.js) {
return "javascript";
} else {
return "java";
}
}
const result = studyCourse(Course.ts);
console.log(`我要学习${result}`);
高级写法:
enum Course {
ts,
js,
java,
};
function studyCourse(course: any) {
if (course === Course.ts) {
return "Typescript";
} else if (course === Course.js) {
return "javascript";
} else {
return "java";
}
}
const result = studyCourse(Course.ts);
console.log(`我要学习${result}`);
这就是枚举的用法,从这就可以看出这枚举的默认下标就是从0开始的,其余的成员会从 1 开始自动增长。
6.2字符串数值
enum Course {
ts="typescript",
js="javascript",
java="java",
};
以上代码对于的 ES5 代码如下:
var Course;
(function (Course) {
Course["ts"] = "typescript";
Course["js"] = "javascript";
Course["java"] = "java";
})(Course || (Course = {}));
;
6.3异构枚举
异构枚举的成员值是数字和字符串的混合:
enum Enum {
A,
B,
C = "C",
D = "D",
E = 8,
F,
}
console.log(Enum.A);
console.log(Enum[0]);
console.log(Enum.C);
console.log(Enum.E);
以上代码对于的 ES5 代码如下:
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
Enum[Enum["B"] = 1] = "B";
Enum["C"] = "C";
Enum["D"] = "D";
Enum[Enum["E"] = 8] = "E";
Enum[Enum["F"] = 9] = "F";
})(Enum || (Enum = {}));
console.log(Enum.A);
console.log(Enum[0]);
console.log(Enum.C);
编译运行打印的日志如下:
通过观察上述生成的 ES5 代码,我们可以发现数字枚举相对字符串枚举多了 “反向映射”:
\
7、任意值(any)
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型,我们可以使用any类型来标记这些变量:
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let list: any[] = [1, true, "free"];
list[1] = 100;
8、unknown
unknown 是 TypeScript 3.0 引入了新类型,是 any 类型对应的安全类型。
unknown 和 any 的主要区别是 unknown 类型会更加严格:在对unknown类型的值执行大多数操作之前,我们必须进行某种形式的检查,而在对 any 类型的值执行操作之前,我们不必进行任何检查。
我们先看一下他跟 any 的共同点,它跟 any 一样,可以是任何类型:
let value: any;
value = true; // OK
value = 1; // OK
value = "Hello World"; // OK
value = Symbol("type"); // OK
value = {} // OK
value = [] // OK
如果我们换成 unknown,结果一样
let value: unknown;
value = true; // OK
value = 1; // OK
value = "Hello World"; // OK
value = Symbol("type"); // OK
value = {} // OK
value = [] // OK
下面我们看看any和unknown的区别在哪里:
\
let value: any;
value.foo.bar; // OK
value(); // OK
new value(); // OK
value[0][1]; // OK
如果是 unknown 类型,那么结果大不相同:
let value: unknown;
value.foo.bar; // ERROR
value(); // ERROR
new value(); // ERROR
value[0][1]; // ERROR
将 value 变量类型设置为 unknown 后,这些操作都不再被认为是类型正确的。通过将 any 类型改变为 unknown 类型,我们已将允许所有更改的默认设置,更改为禁止任何更改。
9、空值(void)
表示没有任何类型,当一个函数没有返回值时,你通常会见到其返回值类型是 void:
function warnUser(): void {
alert("This is my warning message");
}
实际上只有null和undefined可以赋给void:
let unusable: void = undefined;
10、Null和Undefined
默认情况下null和undefined是所有类型的子类型。 就是说你可以把null和undefined赋值给number类型的变量。
let u:undefined = undefined;
let n:null = null;
11、Never
never类型表示的是那些永不存在的值的类型。never类型是任何类型的子类型,也可以赋值给任何类型
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点,就相当于死循环,一直运行不完
function infiniteLoop(): never {
while (true) {
}
}
在 TypeScript 中,可以利用 never 类型的特性来实现全面性检查,具体示例如下:
type Foo = string | number;
function controlFlowAnalysisWithNever(foo: Foo) {
if (typeof foo === "string") {
// 这里 foo 被收窄为 string 类型
} else if (typeof foo === "number") {
// 这里 foo 被收窄为 number 类型
} else {
// foo 在这里是 never
const check: never = foo;
}
}
注意在 else 分支里面,我们把收窄为 never 的 foo 赋值给一个显示声明的 never 变量。如果一切逻辑正确,那么这里应该能够编译通过。但是假如后来有一天有人修改了 Foo 的类型:
type Foo = string | number | boolean;
然后他忘记修改controlFlowAnalysisWithNever 方法中的控制流程,这时候 else 分支的 foo 类型会被收窄为 boolean 类型,导致无法赋值给 never 类型,这时就会产生一个编译错误。通过这个方式,我们可以确保controlFlowAnalysisWithNever 方法总是穷尽了 Foo 的所有可能类型。 通过这个示例,我们可以得出一个结论:使用 never 避免出现新增了联合类型没有对应的实现,目的就是写出类型绝对安全的代码。
12、类型断言
类型断言的两种形式。
12.1 尖括号语法:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
12.2 as语法
let someValue: any = "this is a string";
let strLength: number = (someValue as string)
当你在TypeScript里使用JSX时,只有as语法断言是被允许的。