基本使用
基本类型的注解
很简单 variableName: TypeAnnotation 即可,例:
let num: number;
let str: string;
let bool: boolean;
数组类型
数组类型用 :TypeAnnotation[] 表示,例:
let boolArray: boolean[];
接口
能合并众多类型声明至一个类型声明
例:
interface Name {
first: string;
second: string;
}
let name: Name;
name = {
first: 'John',
second: 'Doe'
};
内联注释语法
与接口不同,但是也可以实现接口的功能,好处在于不用单独去定义一个接口,省去了取名的麻烦,适用于仅使用一次的接口
let name: {
first: string;
second: string;
};
name = {
first: 'John',
second: 'Doe'
};
特殊类型
any⇒ 关闭类型检查,可以使用任何类型null⇒ 可赋值给任何类型的变量undefined⇒ 同nullvoid⇒ 表示函数无返回值
泛型
当无法确定入参时又想将返回值强制类型,可以考虑使用泛型,它将自动识别入参的类型并且将返回值的类型设置的与入参一样。例:
function reverse<T>(items: T[]): T[] {
const toreturn = [];
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items[i]);
}
return toreturn;
}
const sample = [1, 2, 3];
let reversed = reverse(sample);
console.log(reversed); // 3, 2, 1
// Safety
reversed[0] = '1'; // Error
reversed = ['1', '2']; // Error
reversed[0] = 1; // ok
reversed = [1, 2]; // ok
事实上,JavaScript 数组已经拥有了 reverse 的方法,TypeScript 也确实使用了泛型来定义其结构:
interface Array<T> {
reverse(): T[];
}
这意味着,当你在数组上调用 .reverse 方法时,将会获得类型安全
联合类型(支持多类型)
联合类型它使用 | 作为标记,如 string | number
例:
let name: string[] | string
注意:当联合类型的子类型非基本类型时,联合类型读取时仅显示其共同的属性名,联合类型赋值时只能选择子类型之一。
交叉类型
交叉类型它使用 & 作为标记,如 string & number
注意:当交叉类型的子类型非基本类型时,交叉类型读取时显示所有的属性名,交叉类型赋值时无法赋值属性名相同但是类型不同的属性(将会变为never类型)
元祖类型
在JS里原本并不支持元祖,通常只能用数组来表示元祖。
通常形式为::[typeofmember1, typeofmember2]
类型别名
类型别名可以理解为另外一种非对象的interface 的写法
用法:type SomeName = someValidTypeAnnotation
type StrOrNum = string | number;
// 使用
let sample: StrOrNum;
sample = 123;
sample = '123';
// 会检查类型
sample = true; // Error
声明文件
declare 用来声明已经存在的代码,一般声明都会放在独立的.d.ts中可以命名一个global.d.ts 文件用于存放声明
枚举类型
枚举类型实际是就是默认从0下标开始的对象
enum color {
red,
blue,
yellow
}
改变原有的枚举的数字逻辑
默认情况下,第一个枚举值是 0,然后每个后续值依次递增 1:
enum Color {
Red, // 0
Green, // 1
Blue // 2
}
但是,你可以通过特定的赋值来改变给任何枚举成员关联的数字,如下例子,我们从 3 开始依次递增:
enum Color {
DarkRed = 3, // 3
DarkGreen, // 4
DarkBlue // 5
}
字符串枚举
这是最常用也是最好用的一种枚举用法,可以覆盖我们大多数的使用的情况
enum EvidenceTypeEnum {
UNKNOWN = '',
PASSPORT_VISA = 'passport_visa',
PASSPORT = 'passport',
SIGHTED_STUDENT_CARD = 'sighted_tertiary_edu_id',
SIGHTED_KEYPASS_CARD = 'sighted_keypass_card',
SIGHTED_PROOF_OF_AGE_CARD = 'sighted_proof_of_age_card'
}
函数
参数注解
最开始说的所有方法都可以使用,内联,接口等
function foo(**sampleParameter: { bar: number }**) {}
返回类型的注解
可以在函数参数列表之后使用与变量相同的样式来注解返回类型
interface Foo {
foo: string;
}
// Return type annotated as `: Foo`
function foo(sample: Foo): Foo {
return sample;
}
但是也不需要注解返回类型,编译器也会进行自动推断
但是添加可以帮助你错误提示!
function foo(sample: Foo) {
return sample; // inferred return type 'Foo'
}
可选参数 | 参数默认值
function foo(bar: number, bas?: string): void {
// ..
}
foo(123);
foo(123, 'hello');
function foo(bar: number, bas: string = 'hello') {
console.log(bar, bas);
}
foo(123); // 123, hello
foo(123, 'world'); // 123, world
函数方法重载
方法重载是函数中一个很重要的概念,它可以通过传入参数的不同来使函数得到不同的效果
// 重载
function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);
// Actual implementation that is a true representation of all the cases the function body needs to handle
function padding(a: number, b?: number, c?: number, d?: number) {
if (b === undefined && c === undefined && d === undefined) {
b = c = d = a;
} else if (c === undefined && d === undefined) {
c = a;
d = b;
}
return {
top: a,
right: b,
bottom: c,
left: d
};
}
// 调用
padding(1); // Okay: all
padding(1, 1); // Okay: topAndBottom, leftAndRight
padding(1, 1, 1, 1); // Okay: top, right, bottom, left
padding(1, 1, 1); // Error: Not a part of the available overloads
这样也可以让调用者只能输入固定数量的入参,如果没有使用方法重载的情况下允许参入四个参数时,调用者可能会传入不合法的三个参数导致出现错误。
函数声明
在没有提供函数实现的情况下,有两种声明函数类型的方式:
// 函数重载只能用这种方式
type LongHandAllowsOverloadDeclarations = {
(a: number): number;
(a: string): string;
};
// 箭头函数声明方法(函数重载不能用哦~)
type ShortHand = (a: number) => number;
上面代码中的两个例子完全相同。但是,当你想使用函数重载时,只能用第一种方式:
类型断言
在编译时,类型断言技术可以来覆盖浏览器的推断(报错)
例如:
const foo = {};
foo.bar = 123; // Error: 'bar' 属性不存在于 ‘{}’
foo.bas = 'hello'; // Error: 'bas' 属性不存在于 '{}'
这里的代码发出了错误警告,因为 foo 的类型推断为 {},即没有属性的对象。因此,你不能在它的属性上添加 bar 或 bas,你可以通过类型断言来避免此问题:
interface Foo {
bar: number;
bas: string;
}
const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';