目录
一、概述
二、开发环境
三、数据类型
1.boolean
2.number
3.string
4.Array
5.type
6.tuple
7.enum
8.any
9.null / undefined
10.never
11.object
结束
一、概述
TypeScript 是一种由微软开发的开源编程语言。它是 JavaScript 的一个超集,这意味着它在 JavaScript 的基础上进行了扩展,添加了一些新的特性,最主要的特性就是静态类型系统。这些类型不仅提供了代码的类型校验,还能增强编辑器和IDE的功能,例如代码自动完成、接口定义跳转、重构代码等。
静态类型系统的主要优点之一是能在代码运行之前发现潜在的错误,这对大型项目或团队协作尤其有用。它还有助于文档化代码,因为类型注解和接口提供了有关如何使用代码的清晰指导。
TypeScript 的代码在运行之前需要被编译成 JavaScript,因为浏览器和大多数JavaScript环境(如Node.js)不直接执行TypeScript。TypeScript 编译器(tsc)可以编译为 ES5、ES2015 或更高版本的 JavaScript,以确保兼容性。
TypeScript 的关键特性包括:
1. 类型注解和编译时类型检查。
2. 支持最新的 JavaScript 特性,并且可以编译成旧版 JavaScript 代码。
3. 类型推断,即在没有明确注解的情况下猜测变量的类型。
4. 代码自动完成和智能感知使开发更加高效。
5. 接口和泛型支持高度可重用的代码。
6. 枚举类型(Enums)提供了一个标准化的方法来处理一组固定的相关值。
7. 兼容性好,可以在任何支持 JavaScript 的平台上运行。
由于这些特性,TypeScript 已经在开发社区中变得非常流行,尤其是在构建大型或复杂的前端应用程序时。许多现代的前端框架和库,如 Angular,都采用了 TypeScript 作为其主要编程语言。
二、开发环境
百度看了一些帖子,TypeScript 用 Visual Studio Code 编辑器,配合 Node.js 去运行代码,提前还要将 TypeScript 编译成 js 文件,然后去运行 JavaScript 代码,还要修改配置文件,非常的麻烦,我就懒的折腾了,直接在 Cocos Creator 中去运行。
新建一个项目,名字随意,打开项目后,在资源管理器中可以新建一个脚本 test1
脚本的用法和 Unity3d 差不多,直接将脚本拖动到游戏场景中的节点上即可。
由于开发环境在 Cocos Creator 中,和网上很多资料中的写法会有一定的差异,这里以 Cocos Creator 开发环境为准。
三、数据类型
1.boolean
布尔类型,表示逻辑值:true 和 false。
打开test1.ts
代码中随便弄一个打印,然后保存
import { _decorator, Button, Component, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('test1')
export class test1 extends Component {
private a:boolean = false;
start() {
console.log("结果是:" + this.a)
}
update(deltaTime: number) {
}
}
点击 Cocos Creator 运行按钮,在打印的最后一行,就可以看到结果:
在后续教程中,我就贴出 test1.ts 中的部分代码了。
2.number
双精度 64 位浮点值,它可以用来表示整数和分数。需要注意的是 TypeScript 和 JavaScript 没有整数类型。
private x:number = 3;
private y:number = 5;
start() {
console.log("结果是:" + (this.x + this.y));
}
结果:
3.string
字符串类型,文本类型
private myName:string = "张三";
start() {
console.log("名字是:" + this.myName);
}
结果:
4.Array
数组,数组的用法可以有多种
private arr:Array<number> = [1,2,3,4,5,6];
start() {
for (let i = 0; i < this.arr.length; i++) {
const element = this.arr[i];
console.log(element);
}
}
结果:
如果是在方法内部,这么写也没问题
start() {
let arr:Array<number> = [1,3,5];
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
console.log(element);
}
}
数组的类型,可以是任意类型 any
start() {
let arr:Array<any> = [1,"d",false];
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
console.log(element);
}
}
结果:
5.type
type 是一种构造,用于为一组值定义一个类型别名。
type的用法特别多,例如:
用于创建类别别名
start() {
type userName = string;
let name:userName = "张三";
console.log(name);
}
声明对象的类型
start() {
type user = {
id:string,
name:string,
age:number,
sex:string,
}
let myUser: user = {
id:"1",
name:"张三",
age:18,
sex:"男",
}
console.log(myUser);
}
运行:
联合类型
限制当前类型的值只能是固定的一个或者多个值
start() {
type fruit = "苹果"|"香蕉"|"橘子";
//限制 existingFruits 只能取 fruit 值的三个字符串其中之一
let existingFruits:fruit = "香蕉";
}
这样就只能赋值特定的字符串,如果不是特点的字符串,那么会报错
代码:
start() {
type fruit = "苹果"|"香蕉"|"橘子";
//限制 existingFruits 只能取 fruit 值的三个字符串其中之一
let existingFruits:fruit = "葡萄";
}
效果:
泛型类型别名
代码:
start() {
type myObject<T> = { value:T };
let myString:myObject<string> = {value:"你好"};
let myNumber:myObject<number> = {value:53};
console.log(myString.value);
}
type 的用法还有 交叉类型,映射类型,不过平时用的并不多。
6.tuple
元组(Tuple)是一种特殊的数组类型,它工作方式与数组类似,但它有固定数量的元素,且每个元素都可以是不同的类型。这与常规数组不同,后者通常只有一个元素类型。元组使得存储一个固定大小和已知数据类型元素的集合成为可能。
第一次看 typescript 的元组,我还以为是数组,我还以为自己搞错了,专门在去查了一下资料,确实是元组。
声明元组
let values:[string, number] = ["张三",20];
访问元组
start() {
let values:[string, number] = ["张三",20];
let name = values[0];
console.log(name);
}
元组数组
let users: [string, number][] = [
["Alice", 30],
["Bob", 25],
["Charlie", 35]
];
在 C# 里面,有时候也会遇到需要在方法内返回多个值的情况,这时候元组就很好用了,也不需要去单独写一个类来存储多个返回值,typescript 也可以这么写了。
private getUserNameAndAge(): [string, number] {
// 假设这是从数据库中获取的用户信息
return ["Alice", 30];
}
let [userName, userAge] = getUserNameAndAge();
console.log(userName); // 输出: Alice
console.log(userAge); // 输出: 30
7.enum
枚举类型,用于定义一组命名常量。
start() {
enum direction{
up,
down,
left,
right
}
let dir: direction = direction.down;
console.log(dir);
}
运行:
枚举是有默认值的,一般是从 0 开始,down 是排在第二个位置,所以值是1,这里其实也可以自定义枚举的值,比如将 up 设置等于 2,那么 down 的默认值就是 3 了。
枚举的值其实不光可以设置为数字,也可以设置为字符串,比如:
start() {
enum result{
success = "success",
failure = "failure"
}
console.log(result.success);
}
运行:
8.any
任意类型,可以是任何类型的值。
在上面章节 Array 中,就有用到了 any,any 类型是一个非常强大的类型,它允许你绕过 TypeScript 的静态类型检查。使用 any 类型的变量,可以被赋予任何类型的值,同时也可以从它那里获取任何类型的值。这使得 any 类型成为了一种逃避类型系统限制的“后门”。
虽然 any 类型在某些情况下非常有用,但过度使用它会削弱 TypeScript 提供的类型安全保障。使用 any 类型意味着 TypeScript 编译器无法检查类型相关的错误,这可能导致运行时错误。因此,推荐在不得不使用 any 时才使用它,并尽可能地使用 TypeScript 提供的更具体的类型或使用类型断言来进行类型的精确指定。
start() {
let notsure:any = 4;
notsure = "hello";
notsure = false;
console.log(notsure);
}
运行:
9.null / undefined
JavaScript 中的特殊类型,分别指未定义的值和空值。
在 TypeScript 中,null 和 undefined 各自有自己的类型,分别命名为 null 和 undefined。默认情况下,它们分别只有各自的值:null 只能被赋值为 null,undefined 只能被赋值为 undefined。这两种类型是所有其他类型的子类型,这意味着 null 和 undefined 可以赋值给大多数类型,例如 number 或 string,除非你在 TypeScript 配置中启用了严格的空检查(strictNullChecks 选项)。
使用 strictNullChecks
当开启了 strictNullChecks 选项,null 和 undefined 将只能赋值给 any 和它们各自的类型(以及 void 对于 undefined)。这增加了类型安全性,因为你需要显式地处理 null 和 undefined 的可能性。如果一个类型可能是 null 或 undefined,你需要使用联合类型来声明它。
示例:
start() {
this.printLength("你好");
}
private printLength(str: string | null) {
if (str === null) {
console.log('The string is null');
} else {
console.log("字符串长度:" + str.length);
}
}
运行:
如果传入 null
start() {
this.printLength(null);
}
private printLength(str: string | null) {
if (str === null) {
console.log('The string is null');
} else {
console.log("字符串长度:" + str.length);
}
}
运行:
10.never
never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。这意味着声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)
start() {
let x:never;
// 编译错误,数字类型不能转为 never 类型
x=123;
}
这么写是报错的
返回值为 never 的函数可以是抛出异常的情况
start() {
this.error("dd");
}
// 返回值为 never 的函数可以是抛出异常的情况
private error(message: string): never {
throw new Error(message);
}
运行:
返回值为 never 的函数可以是无法被执行到的终止点的情况
start() {
this.loop();
}
private loop():never{
while(true) {}
}
这样写不要运行,否则 cocos 编辑器会直接卡死
11.object
非原始类型,除 number,string,boolean,symbol,null 或 undefined 之外的类型。
object 类型是用于表示非原始类型的类型。换句话说,除了 number、string、boolean、symbol、null 或 undefined 之外的任何类型都可以被认为是 object 类型。这包括函数、数组、对象字面量等。
当你想要声明一个变量可以持有任何类型的对象(但不是原始值)时,可以使用 object 类型。例如:
start() {
let obj: object;
obj = { name: "Alice", age: 30 }; // 正确
obj = [1, 2, 3]; // 正确
obj = function() {}; // 正确
// obj = 42; // 错误:类型“42”的参数不能赋给类型“object”的参数。
// obj = "Hello"; // 错误:类型“"Hello"”的参数不能赋给类型“object”的参数。
// obj = false; // 错误:类型“false”的参数不能赋给类型“object”的参数。
}
尽管 object 类型很有用,但它并不提供有关对象可能具有的特定结构的信息。这意味着,如果你尝试访问一个使用 object 类型声明的对象上的属性或方法,TypeScript 将会抛出一个错误:
start() {
let obj: object = { name: "Alice", age: 30 };
console.log(obj.name); // 错误:类型“object”上不存在属性“name”。
}
报错:
为了更具体地描述一个对象的结构,你可以使用接口(interface)或类型别名(type)来声明具有特定属性和类型的对象。这不仅可以让你获得类型检查的好处,还可以提高代码的可读性和维护性。
start() {
interface Person {
name: string;
age: number;
}
let person: Person;
person = { name: "Alice", age: 30 }; // 正确
// 错误:属性“age”在类型“{ name: string; }”中缺失,但在类型“Person”中是必需的。
// person = { name: "Bob" };
}
报错:
或者使用类型别名:
start() {
type Animal = {
species: string;
age: number;
}
let animal: Animal;
animal = { species: "Dog", age: 5 }; // 正确
}
结束
如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言
end