如何引入并正确执行TS
1、当前浏览器是不认识TS的,需要转化为js
2、使用webpack的 ts-loader
3、必须创建tsconfig.json文件,并做对应配置
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true
}
}
typeScript支持的类型
1、javascript支持的类型
string
number
bolean
null
undefined
symbol
bigint
object: Array Date
2、自有类型
any
1)、可以赋值任何类型变量
let a: any
a = 1
a = false
a = '2'
2)、可以赋值给任意类型的变量 最好不要使用
let b: string
b = a
unknow
1)、可以赋值任何类型变量
let a: unknow
a = 1
a = false
a = '2'
2)、不可以赋值给任意类型的变量
let b: string
b = a // 报错
3)、赋值给其它变量时,需要提前声明确认当前类型
// 第一种
if (typeof a === 'string') {
b = a
}
// 第二种 不安全
b = a as string
// 第三种 不安全
b = <string>a
4)、就算当前赋值是字符串也不能使用 .toUpperCase() 方法,需要使用3
never 几乎不会用到
1)、不要用于定义变量
2)、TS自己推断值类型
3)、特殊中断函数的返回值,即函数不可能执行完成
function fn(): never {
throw new Error('中断')
}
void
1)、用于定义函数返回值
2)、函数返回值为undefined或没有return,即没有返回值
function fn(): void {
}
function fn(): void {
return undefined
}
function fn(): void {
return
}
3)、不能使用函数的返回值去做其他逻辑
let result = function fn(): void {
return undefined
}
<!-- 报错 -->
if (result) {
}
object
1)、非基础类型都可以
Object
1)除了 null、undefined 其余都可以赋值
声明对象
<!-- 属性必须是指定类型、属性数量不能多也不能少 -->
let person: { name: string, age: number }
person = {
name: 'jack',
age: 12
}
<!-- 使用 ?: 表示当前属性非必要 -->
let person: { name: string, age?: number }
person = {
name: 'jack'
}
<!-- [key: string]: any 可以添加未定义的属性, 此时 获取 未定义的属性 也不会报错,返回undefined -->
let person: { name: string, age?: number, [key: string]: any }
person = {
name: 'jack',
hobby: '篮球'
}
console.log(person.a)
声明函数
let count: (a: number, b: number) => number
count = function(a, b) {
return a + b
}
声明数组
let arr1: string[] = []
let arr2: Array<number> = []
arr1.push('12')
arr2.push(12)
tuple 元组,一种特殊的数组类型,不是关键字
<!-- 数组必须是两个元素,第一个是数字,第二个是字符串 -->
let arr1: [number, string]
<!-- 数组最多2个元素,第一个是数字,第二个是布尔类型,第二个可以不写 -->
let arr2: [number, boolean?]
<!-- 数组至少有一个元素,最大不限制,且第一个必须是数字,其他元素必须是字符串 -->
<!-- 这种写法只能, 只能包含一个 ...rest -->
let arr3: [number, ...string[]]
arr1 = [1, '2']
arr2 = [1]
arr1 = [1, '2', '3', '4']
enum 枚举
1)、数字枚举
<!-- 不指定数字时,默认从0开始顺序赋值 -->
enum Direction {
Up,
Down,
Left,
Right
}
<!-- 可以指定,如下面,Left6开始 -->
enum Direction {
Up = 3,
Down = 5,
Left,
Right
}
<!-- 但不要间隔赋值,且没有留足够自增值给中间的key,如下面,Left也是6,就重复了 -->
enum Direction {
Up = 3,
Down = 5,
Left,
Right = 6
}
function go(data: Direction) {
switch (data) {
case Direction.Up:
console.log('向上')
break;
case Direction.Down:
console.log('向下')
break;
case Direction.Left:
console.log('向左')
break;
case Direction.Right:
console.log('向右')
break;
default:
console.log('停留')
break;
}
}
console.log(Direction)
// {0: 'Up', 1: 'Down', 2: 'Left', 3: 'Right', Up: 0, Down: 1, Left: 2, Right: 3}
go(Direction.Down)
go(Direction.Left)
2)、字符串枚举
<!-- 每个有特定值,没有反向枚举 -->
enum Direction {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
console.log(Direction)
// {Up: 'up', Down: 'down', Left: 'left', Right: 'right'}
3)、常量枚举
const enum Direction {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
<!-- 编译简化,去除未使用的值 -->
<!-- 不能直接打印 Direction -->
console.log(Direction.Up)
type 定义类型
type Age = number
let age: Age
type Time = number | string
let time: Time
time = '2024-12-31 12:12:12'
time = Date.now()
type Kitchen = {
gasStove: number;
knife: number;
clean: boolean;
}
type Bedroom = {
bed: number;
closet: number;
}
type Room = Kitchen & Bedroom
let room: Room
room = {
gasStove: 1,
knife: 2,
clean: true,
bed: 1,
closet: 2
}
type Fun = () => void
let fn1: Fun
<!-- 虽然返回值定义为 void, 但依然可以返回任意类型 -->
fn1 = () => 66
let x = fn1()
console.log(x)
<!-- 此时 不能执行下面的代码,因为void 不能参与任何逻辑判断及运算 -->
if (x) {
}
属性装饰符
1)、public
class Person {
public name: string
public age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
public sayHello() {
console.log(`你好,我是${this.name}`)
}
}
let p = new Person('jack', 12)
console.log(p.name)
console.log(p.age)
p.sayHello()
class Person {
constructor(
public name: string,
public age: number
) {}
sayHello() {
console.log(`你好,我是${this.name}`)
}
}
class Student extends Person {
constructor(
public name: string,
public age: number,
public className: string
) {
super(name, age)
}
}
2)、protected
class Person {
constructor(
protected name: string,
protected age: number
) {}
protected sayHello() {
console.log(`你好,我是${this.name}`)
}
forceSayHello() {
this.sayHello()
}
}
let p = new Person('jack', 12)
<!-- 不可调用 -->
// p.name
// p.age
// p.sayHello()
<!-- 可正常调用 -->
p.forceSayHello()
3)、private
class Person {
constructor(
private name: string,
private age: number
) {}
private sayHello() {
console.log(`你好,我是${this.name}`)
}
forceSayHello() {
this.sayHello()
}
}
<!-- 此时 类 Student 会报错 -->
<!-- 类“Student”错误扩展基类“Person”。
类型具有私有属性“name”的单独声明。 -->
class Student extends Person {
constructor(
private name: string,
private age: number,
private className: string
) {
super(name, age)
}
}
4)、readonly
class Person {
constructor(
readonly name: string,
public age: number
) {}
sayHello() {
console.log(`你好,我是${this.name}`)
}
forceSayHello() {
this.sayHello()
}
}
class Student extends Person {
constructor(
readonly name: string,
public age: number,
public className: string
) {
super(name, age)
}
}
let p = new Person('jack', 12)
<!-- 不可修改 -->
// p.name = 'tom'
<!-- 其他操作都可以 -->
p.age = 20
p.name
p.age
p.sayHello()
p.forceSayHello()
abstract 抽象类
abstract class Person {
constructor(
public name: string,
public age: number
) {}
abstract sayHello(): void
forceSayHello() {
this.sayHello()
}
}
class Student extends Person {
constructor(
public name: string,
public age: number,
public className: string
) {
super(name, age)
}
sayHello(): void {
console.log(`我是${this.name}, 今年${this.age}岁了`)
}
}
let student1 = new Student('tom', 12, '一班')
student1.sayHello()
student1.forceSayHello()
interface
interface PersonInterface {
name: string
age: number
inSchool: boolean
sayName: () => string
}
class Person implements PersonInterface {
constructor(
public name: string,
public age: number,
public inSchool: boolean
) {}
sayName = () => {
return this.name
}
}
let p = new Person('jack', 12, true)
interface Person {
name: string
age: number
inSchool: boolean
[key: string]: any
}
const person: Person = {
name: 'jack',
age: 12,
inSchool: true,
hobby: '篮球'
}
interface GetNameInterface {
(name: string, age: number): string
}
let fn: GetNameInterface = (name, age) => {
return name
}
interface PersonInterface {
name: string
age: number
}
interface Student extends PersonInterface {
className: string
}
let student1: Student = {
name: 'jack',
age: 20,
className: '一班'
}
interface PersonInterface {
name: string
age: number
}
interface Student extends PersonInterface {
className: string
}
interface Student {
siteNum: number
}
let student1: Student = {
name: 'jack',
age: 20,
className: '一班',
siteNum: 1001
}
泛型
<!-- T 可以是任意自定义字符,可定义多个,用逗号隔开 -->
<!-- 参数在调用时在确定类型 -->
function getData<T, U>(data1: T, data2: U) {
console.log(data1, data2)
}
getData<string, number>('2', 2)
getData<object, boolean>({ a: 2 }, true)
interface PersonInterface<T> {
name: string
age: number
others: T
}
let person: PersonInterface<string> = {
name: 'jack',
age: 23,
others: '篮球'
}
interface PersonInterface<T> {
name: string
age: number
others: T
}
interface HobbyInterface {
game: string
color: string
num: number
}
let person: PersonInterface<HobbyInterface> = {
name: 'jack',
age: 23,
others: {
game: 'LOL',
color: 'red',
num: 66,
}
}
declare 类型声明文件
把js文件生成对应.d.ts文件,做TS注解 一般用不到