TypeScript(一) 类型和类型注解

本文详细介绍了TypeScript的基础概念、配置文件设置、内置对象类型声明、作用域问题、基本数据类型、类型注解等内容,帮助读者快速理解和上手TypeScript。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TypeScript 概述

TypeScript 基于 Javascript 基础之上的编程语言,是 JavaScript 的超集,或者叫扩展集。所谓超集就是在JavaScript 原有的基础上多了一些扩展特性,多出来的其实是一套更强大的类型系统,以及对 ECMAScript的新特性支持,它最终会编译成原始的 JavaScript。

因为TypeScript最终会编译成JavaScript去工作,所以任何一种Javascript运行环境都支持,例如我们传统的浏览器应用,或者是node应用,reactNative,桌面应用Electron,它们都可以使用TypeScript来开发。相比于Flow,TypeScript作为一门完整的编程语言,他的功能更为强大,生态也更健全、更完善。

一、快速上手&配置文件&标准库声明 (内置对象类型)&作用域问题

1.快速上手

  1. 安装

    yarn add typescript --dev 安装完成之后在 node_modules/.bin 中 有一个 tsc
    检查版本号:tsc -v

    执行上面指令,下载的node安装包

  2. 编译转换

    yarn tsc [文件名] 命令执行后会生成一个js文件

    编译前

    // text.ts
    (() => {
      const username: string = "迪西";
      console.log(username);
    })();
    

    编译后

    // text.js
    (function () {
        var username = "迪西";
        console.log(username);
    })();
    

在这里插入图片描述
注:1.使用 tsc 命令转js的时候一定要和前面的路径拼成你的Test.ts文件所在的路径 ,如上图所示 。否则就提示 error TS6053: File ‘Test.ts’ not found.
2. 如果没有其他的设置,再html中直接引入ts文件会报错,需要引入转换后的js文件

2.配置文件

tsc命令不仅仅可以去编译指定某个ts文件,它还可以去编译整个项目,编译整个工程。
  1. 创建 TypeScript 配置文件

    yarn tsc --init
    命令之后,会生成一个 tsconfig.json 文件。
    执行yarn tsc --init命令之后,生存的tsconfig.json文件

  2. 常用的选项
    • target:作用就是用设置编译过后 Javascript 所采用的 ECMA 标准;
    • module:输出的代码采用什么样的方式去进行模块化;
    • outDir:设置编译结果输出到的文件夹,一般我们会输出到 dist 文件夹;
    • rootDir:配置我们源代码,也就是 Typescript 的代码所在的文件夹,一般我们会把源代码放在src目录;
    • sourceMap:开启源代码映射,开启之后,调试的时候可以 sourceMap 文件进行调试源代码;
    • strict:开启所有严格检查选项,严格模式下,需要我们对每一个成员都要指定明确的类型等等;
      需要注意的是,如果我们还是使用 tsc 编译某个 ts 文件时,配置文件是不起作用的,只有当我们直接运行tsc命令去编译整个项目时,配置文件才生效。

3.标准库声明 (内置对象类型)

	标准库就是内置对象所对应的声明,我们在代码中使用内置对象,就必须要引用对应的标准库,否则 typescript 就会找不到对应的类型,就会报错。

可通过配置文件lib选项添加我们要使用的标准库:

{
  "compilerOptions": {
    "lib": ["es2015", "DOM"]
  }
}

4.作用域问题

不同文件可能会存在相同名称的变量,比如 a 文件定义了一个全局的变量 a,b文件也定义了一个全局变量 a,那么就会产生异常。
解决方法

  1. 用一个立即执行函数创建一个单独的作用域
    (function () {
    	    const username: string = "迪西";
    	})()
    
  2. 使用export 导出,这样的话这个文件就会作为一个模块导出,模块有单独的模块作用域
    const username: string = "迪西";
    export {}
    

注: export后面的{ },是export 的语法,并不是表示导出一个空对象
当然,这样的一个问题在实际开发并不会用到,因为在绝大多数情况下,每个文件都会以模块的形式去工作。

二、基本类型

1.数字类型

数字类型,可以更精确地定义变量的值。数字类型可以包括整数和浮点数。
let age: number = 9;
let price: number = 29.99;
console.log(age); // 9
console.log(price); // 29.99
age = 10; // 正确
// price = "20.00"; // 错误,提示类型不匹配

2.字符串类型

字符串类型用于表示文本
let username: string = "迪西";
let greeting: string = 'Hello, 迪西!';
console.log(username); // 迪西
console.log(greeting); // Hello, 迪西!
// username = true; // 错误,类型不匹配

3.布尔类型

布尔类型在 TypeScript 中用于表示逻辑值 true 或 false。
let isDisabled: boolean = true;
let isOnly: boolean = false;
console.log(isDisabled); // true
console.log(isOnly); // false
// isDisabled = 1; // 错误,类型不匹配

4.数组类型

数组是一种容纳多个元素的数据结构,可以使用 number[] 或 Array<number> 来声明数字类型的数组。
// 使用元素类型 + [ ]
let usernames: string[] = ['迪西', '丁丁', '拉拉', '小波']; 
// 使用 Array 泛型
let nums: Array<number> = [1, 2]; 

console.log(usernames); // ['迪西', '丁丁', '拉拉', '小波']
console.log(nums); // [1, 2]

5.元组类型

元组是一个明确元素数量以及每一个元素类型的数组。
元组是一种具有固定长度和特定类型的数组。.在 TypeScript 中,可以使用元组类型来定义。将不匹配类型的数组赋值给 元祖 将导致错误。
// 定义元组类型的方式:可类似数组字面量
let person: [string, number] = ['迪西', 11];
console.log(person); //  ['迪西', 11]
// 访问元组当中元素的方式
//1. 可以使用数组下标的方式去访问
console.log(person[0]); // 迪西
console.log(person[1]); // 11
//1. 使用数组解构的方式去提取
const [age, name] = tuple
console.log(age, name) // 11  '迪西'
// person = ["丁丁", "13"]; // 错误,类型不匹配

元组一般用于一个函数中返回多个返回值

onst entries: [string, number][] = Object.entries({
  foo: 12,
  bar: 34
})

const [key, value] = entries[0]
// key => foo, value => 12

6.空和未定义

null 或 undefined,表示一个变量可能是空或未定义的状态
let mayNull: string | null = null;
let mayUndefined: number | undefined = undefined;
console.log(mayNull); // null
console.log(mayUndefined); // undefined
// mayNull = 23; // 错误,类型不匹配

7.任意类型

any 类型,不确定变量的类型,或者希望一个变量可以接受任何类型的值
any 类型,typescript 不会去做类型检查,仍然会存在类型安全的问题。所以不要轻易去使用这种类型。
let anyType: any = 42;
console.log(anyType); // 42
anyType = "嘻嘻";
console.log(anyType); // 嘻嘻
anyType = true;
console.log(anyType); // true

8.联合类型

联合类型, 允许变量具有多种类型之一,通过使用 | 运算符。
let unionType: string | number = "迪西"; // unionType字段可以是字符串或number, 若赋值boolean类型将提示类型不匹配
console.log(unionType); // 迪西
unionType = 42;
console.log(unionType); // 42

9.交叉类型

交叉类型,允许将多个类型合并为一个类型,通过使用 & 运算符。
interface Person {
  name: string;
  age: number;
}
interface likeTerms {
  HobbiesSubject: () => void;
}

let autonomousCar: Person & likeTerms = { // & 它们合并成一个新的接口
  name: "迪西",
  age: 10,
  HobbiesSubject: () => {
    console.log("数学");
  },
};
console.log(autonomousCar.name); // 迪西
autonomousCar.HobbiesSubject(); // 数学

10.object 类型(Object Types)

Typescript 中 Object 类型不单是指普通对象类型,它泛指所有的非原始类型,也就是对象,数组还有函数。
// 函数
const fn: object = function () {}
// 普通对象
const obj: object = {}
// 数组
const arr: object = []

如果需要普通对象类型,就要使用类似对象字面量的语法去标记类型,这种对象类型限制,它要求我们赋值对象的结果必须要跟我们标记类型的结构完全一致,不能多,也不能少。

const obj: { foo: number, str: string } = { foo: 123, str: '123' }

更好的方式是使用接口的方式,后面会有文章介绍!

11.函数类型(Function Types)

无非是对输入输出做限制,也就是参数和返回值。
  1. 函数声明的类型限制
  • 基本用法

    function func (a: number, b:number): number{
        return a + b;
    }
    func(100, 200) 
    // 注意:形参和实参个数要一致
    
  • 可选参数

    1. 在参数后面加一个 ? 号
    function func (a: number, b?:number): string {
        return 'func1'
    }
    
    func(100)
    
    1. 使用 es6,添加默认参数,因为添加默认值的参数就可有可无。
    function func (a: number, b:number = 10): string {
        return 'func1'
    }
    
    func(100)
    

    注:使用可选参数或者是默认参数,都必须要在参数列表的最后.

  • 接收任意个数参数
    使用 es6 的 … 操作符.

    function func (a: number, ...rest: number[]): string {
        return 'func1'
    }
    
    func(100, 200, 300, 400)
    
  1. 函数表达式的类型限制
    函数表达式最终是放在一个变量上的,接收这个函数的变量,也是应该有类型的.
    const func = function (a: number, b: number): number{
        return a + b;
    }
    
    typescript一般会根据函数表达式推断出这个变量的类型
    如果是把一个函数作为参数传递,也就是回调函数的方式,一般我们就会去约束我们这个回调函数形参的类型,使用类似箭头函数的方式去表示我们这个参数接收什么类型的函数,这种方式在定义接口的时候经常用到。
    const func: (a: number, b: number) => number = function (a: number, b: number): number {
      return a + b
    }
    console.log(func(10, 20)); // 30
    

12.泛型(Generics)

指的是我们去定义函数,接口,类的时候没有去定义具体类型,我们在使用的时候再去定义指定类型的这一种特征。
特点是极大程度的复用我们的代码。
  • 不使用泛型:

    // 定义一个创建 number 类型的方法
    function createNumArray (length: number, value: number): number[] {
      const arr = Array<number>(length).fill(value)
      return arr
    }
    // 定义一个创建 string 类型的方法
    function createStrArray (length: number, value: string): string[] {
      const arr = Array<string>(length).fill(value)
      return arr
    }
    
    const numArr = createNumArray (3, 100)
    const strArr = createStrArray (3, 'foo')
    
  • 不使用泛型:
    把类型用一个泛型参数 T 表示,把函数当中不明确类型用 T 去代表,在使用的时候再传递具体类型。如下:

    function createArray<T> (length: number, value: T): T[] {
      const arr = Array<T>(length).fill(value)
      return arr
    }
    
    const numArr = createArray<number>(3, 100)
    const strArr = createNumberArray<string>(3, 'foo')
    

    其实 Array 是一个泛型类,在 typescript 中去定义这个 Array 类型时,它不知道我们使用它去存放什么样类型的数据,所以它就使用泛型参数,在我们去调用的时候再传入具体类型,这是一个泛型提现。

    总的来说,泛型就是在我们定义的时候把不明确的类型,变成一个参数,在我们使用的时候再传递这样的一个类型参数。

二、类型注解

在 TypeScript 中,类型注解是提高代码可读性和稳健性的关键,

1.基础类型注解

let username: string = "John";
let age: number = 25; 
let isStudent: boolean = false;
// username 为字符串类型 age为数字类型 isStudent 为布尔类型

2.数组和元组类型注解

数组和元组是 TypeScript 中常见的数据结构,在类型注解中,使用 number[] 表示数组,[string, number]表示元组。
// 元组类型
let person: [string, number] = ['迪西', 11];
console.log(person); //  ['迪西', 11]
console.log(person[0]); // 迪西
console.log(person[1]); // 11
// person = ["Jane", "25"]; // 错误,类型不匹配
// 数组类型
let usernames: string[] = ['迪西', '丁丁', '拉拉', '小波'];
let nums: Array<number> = [1, 2];
console.log(usernames); // ['迪西', '丁丁', '拉拉', '小波']
console.log(nums); // [1, 2]

3.函数类型注解

函数类型注解为函数的参数和返回值明确类型,提高代码的可读性。
// 定义了add函数的参数和返回值类型
function add(x: number, y: number): number {
  return x + y;
}
let result: number = add(3, 7);

4.对象类型注解

对象是 JavaScript 中最常见的数据结构之一,使用类型注解明确对象的结构。
let personInfo: { name: string; age: number } = {
  name: "Alice",
  age: 30,
};

5.联合类型和类型别名注解

通过联合类型和类型别名,使变量可以接受多种类型的值。
type Result = number | string;
function getResult(): Result {
  return Math.random() > 0.5 ? "success" : 404;
}

6.Generics 类型注解

Generics(泛型) 是 TypeScript 中强大的能力,可以创建可重用的、灵活的代码。
function identity<T>(value: T): T {
  return value;
}

let result0: number = identity<number>(9);
let result1: string = identity<string>('迪西');
console.log(result0, result1); // 9 '迪西'
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程楠楠&M

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值