Typescript 基础语法
推荐阅读官方文档
基础类型
数字
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;
字符串
let username: string = `Gene`;
let sentence: string = `Hello, my name is ${username}`
数组
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
布尔值
let isDone: boolean = false;
null, undefine
这两个类型只能赋值给 null 或 undefined
注意:在之前ts的版本中 null 或 undefined 是其他类型的子类型,可以赋值给其他类型,但是后面的版本修改了,只能是 null 或 undefined,更加安全
let n: null = null;
let u: undefined = undefined
元组tuple【ts新增】
ts新增,元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同
let tuple: [string, number] = ['abc', 10]
// let tuple: [string, number] = [100, 10] // 错的
枚举enum【ts新增】
ts新增,enum类型是对JavaScript标准数据类型的一个补充
enum Gender { male = 0, female = 1, unknow = -1 }
let g: number = Gender.male
console.log(g) // 0
// 如果没有指定默认值,则默认值为索引下标,默认从0开始,例如:
enum weekday {sunday, monday}
let d: number = weekday.monday
console.log(d) // 1
let day: weekday = weekday.sunday
console.log(day) // 0
// 也可以通过索引来找到对应的值
let day1: string = weekday[0]
console.log(day1) // sunday
字面量
let num: 1 | 2 | 3
num = 1
// num = 4 // error
any
let notSure: any = 4; // noSure可以是任意js对象
let list3: any[] = [1, true, "free"]; // 由任意对象组成的数组
let list4: Array<any> = [1, true, "free"]; // 由任意对象组成的数组
void
没有任何类型,当函数没有返回值时,可以设置为void
function warnUser(): void {
console.log("This is my warning message");
}
never
返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
function fail() {
return error("Something failed");
}
function infiniteLoop(): never {
while (true) {}
}
类型断言
能确定变量类型的话,就可以使用断言
- “尖括号”语法
let someValue: any = 'some message'; let strLength: number = (<string>someValue).length;
- as语法
在TypeScript里使用JSX时,只有 as 语法断言是被允许的,因为<>语法在jsx中会解析成为元素或组件let someValue1: any = "this is a string"; let strLength2: number = (someValue as string).length;
高级类型
交叉类型
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Student & Gender
同时是 Person 和 Student 和 Gender
。 就是说这个类型的对象同时拥有了这三种类型的成员。
需要合并的需要是接口类型
interface Person {
name: string
age: number
}
interface Student {
school: string
}
interface Gender {
gender: 'male' | 'female'
}
type StudentInfo = Person & Student & Gender
// 正确
let stu: StudentInfo = {
name: 'jerry',
age: 18,
school: 'xxx',
gender: 'male'
}
// 错误,缺少gender
let stu1: StudentInfo = {
name: 'jerry',
age: 18,
school: 'xxx'
}
联合类型
联合类型表示一个值可以是几种类型之一。 我们用竖线( |
)分隔每个类型,所以 number | string | boolean
表示一个值可以是 number
, string
,或 boolean
。
let value: string | number | boolean = '123';
value = 'string'
value = 100
value = true
// value = new Date() // ERROR
如果一个值是联合类型,我们只能访问此联合类型的所有类型里共有的成员。
interface Type1 {
func1(): void;
func2(): void;
}
interface Type2 {
func3(): void;
func2(): void;
}
class Type1Class implements Type1 {
func1(): void {
console.log('func1 run');
}
func2(): void {
console.log('func2 run');
}
}
class Type2Class implements Type2 {
func3(): void {
console.log('func1 run');
}
func2(): void {
console.log('func2 run');
}
}
function getSomeType(type: string): Type1 | Type2 {
if (type === '1') {
return new Type1Class();
}
if (type === '2') {
return new Type2Class();
}
throw new Error(`Excepted Type1Class or Type2Class, got ${type}`);
}
let type = getSomeType('1');
type.func2();
type.func1(); // 报错
type.func3(); // 报错
映射类型
假设我想把接口Person
里的所有属性都设置为只读的或者可选的类型,我们需要重新定义接口吗?其实不用,我们可以使用映射类型,来基于已有的接口,映射出其他的类型
interface Person {
name: string
age: number
}
// 这里 in keyof 可以理解为for循环,把每个泛型属性拿出来,添加上只读修饰符
type personReadonly<T> = {
readonly [P in keyof T]: T[P];
}
type personPartial<T> = {
[P in keyof T]?: T[P];
}
// 使用上面定义的映射,重新声明一个类型
type PersonPartial = personPartial<Person>;
type ReadonlyPerson = personReadonly<Person>;
一个更简单的例子
type Keys = 'option1' | 'option2';
type Flags = { [K in Keys]: boolean };
// 这里Flags 和 Flags1是等效的
type Flags1 = {
option1: boolean;
option2: boolean;
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com