TypeScript 基础语法
TypeScript 基础语法
By understanding JavaScript, TypeScript saves you time catching errors and providing fixes before you run code.
Any browser, any OS, anywhere JavaScript runs. Entirely Open Source.
使用
- 在根目录中,生成 package 文件,
yarn init --dev
- 下载 typescript 依赖,
yarn add typescript --dev
- 使用终端指令编译 ts ,
yarn tsc 文件名
- 生成 TypeScript 配置文件,
yarn tsc --init
-
编译 ts 文件,
yarn tsc
-
编译中文错误提示的文件,
yarn tsc --locale zh-CN
TS 的配置文件
执行 yarn tsc --init
会在根目录生成一个配置文件:tsconfig.json
(还可以设置严格模式等等。)
模块作用域
为了避免全局命名冲突,需要让 ts 文件变成一个模块文件。(或者放在 IIFE 中。)
export {}
类型
原始类型
// 原始类型
const a:string = 'foo';
const b:number = 123;
const c:boolean = true; // false
// const d:boolean = null;
const e:void = undefined;
const f:undefined = undefined;
const g:null = null;
const h:symbol = Symbol(); // es2015 新增类型 需要修改配置文件的 target 或 lib
// 标准库就是内置对象所对应的声明
// const error:string = 100;
对象类型
// Object 类型
export {} // 避免作用域变量冲突
// 除了原始类型以外的所有对象类型
const foo: object = function () {} // [] // {}
// 对象的类型限制:对象字面量
const obj: {foo: number, bar: string} = {
foo: 123,
bar: 'str',
};
数组类型
// 数组类型
const arr1: Array<number> = [1, 2, 3];
const arr2: number[] = [4, 5, 6]; // 常用
function sum (...args: number[]) {
return args.reduce((prev, current) => prev + current, 0);
}
sum(1, 2, 3, 4);
元组类型
// 元组类型 明确元素数量和类型的数组
export {}
const tuple: [number, string] = [1, 'str'];
// const age:number = tuple[0];
// const name = tuple[1];
const [age, name] = tuple;
// ----------------
Object.entries({
foo: 123,
bar: 456
})
枚举类型
// 枚举类型
export {}
// const PostStatus = {
// Draft: 0,
// Unpublished: 1,
// Published: 2
// }
// enum PostStatus {
// Draft = 0,
// Unpublished = 1,
// Published = 2
// }
// enum PostStatus {
// Draft = 6,
// Unpublished, // 7
// Published // 8
// }
// 字符串枚举
// enum PostStatus {
// Draft = "aaa",
// Unpublished = "bbb",
// Published = "ccc"
// }
// 常量枚举
const enum PostStatus {
Draft,
Unpublished,
Published
}
const post = {
title: 'this is a title of the current post',
content: 'Hello TypeScript! This is a typed superset of JavaScript.',
status: PostStatus.Draft // 0 // 1 // 2
}
函数类型
// 函数类型
export {}
function func1 (a:number, b:number = 10, ...rest: number[]):string {
return 'func1'
}
func1(1, 2);
func1(1);
// func1(1, 2, 3);
// 在 b 后面加上?,b 变成可选参数
function func2 (a:number, b?:number):string {
return 'func2'
}
func2(1, 2);
func2(1);
// =====================
// func3 的形参类型限制 + 返回值的类型限制
const func3: (a: number, b: number) => string = function (a:number, b:number):string {
return 'func3'
}
任意类型
// 任意类型
export {}
function stringify (value: any) {
return JSON.stringify(value);
}
stringify(123);
stringify('string');
stringify(true);
let foo: any = '123';
foo = 123;
// any 类型并不安全
隐式类型推断
// 隐式类型推断
export {}
let age = 18; // 此处已推断为 number
// age = '123';
let foo; // any 类型
foo = 123;
foo = 'str';
类型断言
// 类型断言
export {}
const nums = [1, 2, 3, 4, 5];
const res = nums.find(n => n > 2);
// const square = res * res;
const num1 = res as number; // 将 res 明确看作数字类型
const num2 = <number>res; // JSX 中不要使用
接口
// 接口 约束对象结构 必须遵循接口规范
// 可选成员 只读成员 动态成员
export {}
interface Post {
title: string
content: string
subtitle?: string // 可选成员
readonly summary: string // 只读成员
}
function printPost (post: Post) {
console.log(post.title)
console.log(post.content)
}
printPost({
title: 'typescript',
content: 'a surperset of js',
summary: 'a description'
})
// --------------------------
// 动态成员
interface Cache {
[key: string]: string
}
const cache: Cache = {}
cache.foo = '123'
cache.bar = '456'
类
// 类
export {}
class Person {
// 定义对象实例中属性的类型
name: string // = 'init name'
age: number
constructor (name: string, age: number) {
this.name = name
this.age = age
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}.`)
}
}
类中的修饰器
// 类 访问修饰符
export {}
class Person {
// 访问修饰符: public 公有属性
public name: string // = 'init name'
// 访问修饰符: private 私有属性 (不能在外部访问)
private age: number
// 访问修饰符: protected 被保护的属性 (不能在外部访问,但可以在子类访问)
protected gender: boolean
constructor (name: string, age: number) {
this.name = name
this.age = age
this.gender = true
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}.`)
console.log(this.age)
}
}
class Student extends Person {
// 私有类
private constructor (name: string, age: number) {
super(name, age)
console.log(this.gender) // gender 可以在子类访问到
}
static createObj (name: string, age: number) {
return new Student(name, age);
}
}
const mike = new Person('mike', 18);
console.log(mike.name)
// console.log(mike.age)
// console.log(mike.gender)
const jack = Student.createObj('jack', 20);
只读属性
// 类的只读类型
export {}
class Person {
public name: string // = 'init name'
private age: number
// 只读属性 readonly
protected readonly gender: boolean
constructor (name: string, age: number) {
this.name = name
this.age = age
this.gender = true
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}.`)
console.log(this.age)
}
}
const mike = new Person('mike', 18);
console.log(mike.name)
类与接口
// 类 与 接口
export {}
interface Eat {
eat (food: string): void
}
interface Run {
run (distance: number): void
}
class Human implements Eat, Run {
eat (food: string): void {
console.log(`吃了${food}`)
}
run (distance: number): void {
console.log(`走了${distance}`)
}
}
class Animal implements Eat, Run {
eat (food: string): void {
console.log(`进食${food}`)
}
run (distance: number): void {
console.log(`爬了${distance}`)
}
}
抽象类
// 抽象类
export {}
abstract class Animal {
eat (food: string): void {
console.log('吃吃吃', food)
}
abstract run (distance: number): void
}
class Dog extends Animal {
run (distance: number): void {
console.log('走一走', distance)
}
}
const d = new Dog();
d.eat('cakes');
d.run(100);
泛型
// 泛型 在声明时不去指定声明类型,等到调用时再去传递具体的类型
export {}
function createNumberArray (length: number, value: number):number[] {
const arr = Array<number>(length).fill(value)
return arr
}
function createStringArray (length: number, value: string):string[] {
const arr = Array<string>(length).fill(value)
return arr
}
// 泛型
function createArray<T> (length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr
}
const res = createNumberArray(3, 100) // [100, 100, 100]
const res2 = createArray<string>(3, '100') // ['100', '100', '100']
类型声明
// 类型声明
import { cameCase } from 'lodash'
// 声明函数类型
declare function cameCase(input: string):string
const res = cameCase('typed javascript')
export {}
如果不写类型声明,那么用 npm i --save-dev @types/lodash
来下载官方提供的 ts 类型声明文件!