当前位置: 首页 > news >正文

TS学习笔记

快速浏览

ts可以自动识别js的变量类型

const message: string = "Hello, TypeScript!";
console.log("variable type is meaaage: " + message);

使用interface定义一个接口,可以显示的声明变量类型

interface Person {name: string;age: number;
}const person: Person = {name: "John",age: 30
};console.log("interface :" + person.name);

interface与class之间的联合使用 (不理解为什么要这要用)

注:这里的constructor是类的构造器

interface User{name: string;age: number;
}class UserAccount {name: string;age: number;constructor(name: string, age: number){this.name = name;this.age = age;}
}const user: User = new UserAccount("Tom", 25);
console.log("interface and class :"+user.name);

接口的一些作用

interface Shape{height: number;width: number;
}// 1. 规定返回类型
function xxx(): Shape{const shape : Shape = {height: 10,width: 20}return shape;}//2.参数类型的约束
function aaa(shape: Shape){//...
}

联合

组合类型
联合 (这些变量只能取其中的一个)

type myBool = true | false;
type myString = "hello" | "the world";

联合在函数参数中的使用
该函数将参数统一封装成数组对象

function wrapInArray(obj: string | string[]): any[]{if(typeof obj === "string") return [obj];return obj;
}

要了解变量的类型, 使用 typeof

类型推断语句
stringtypeof s === "string"
numbertypeof n === "number"
booleantypeof b === "boolean"
undefinedtypeof undefined === "undefined"
functiontypeof f === "function"
arrayArray.isArray(a)

泛型

  1. 什么是泛型

泛型就是:给类型加上“变量”,这样函数、类或接口就可以在不固定具体类型的情况下复用。
换句话说,泛型 = 类型的参数化

比如普通函数:

function identity(arg: number): number { return arg; }

只能处理 number 类型。

如果我想让它既能处理 number,也能处理 string,也能处理 boolean
这时就需要 泛型


  1. 基本语法
function identity<T>(arg: T): T {   return arg; 
}
  • T 就是泛型参数(相当于“类型变量”)。
  • 调用时可以指定类型:
    identity<string>("hello");     // 返回 "hello" identity<number>(42);          // 返回 42
  • 也可以让 TypeScript 自动推断:
identity("hello");  // 推断 T 为 string 
identity(42);       // 推断 T 为 number

  1. 泛型的常见用法

(1) 泛型函数

function wrapInArray<T>(value: T): T[] {   return [value]; 
}  wrapInArray("hi");   // 类型: string[] 
wrapInArray(100);    // 类型: number[]

(2) 泛型接口

interface Box<T> {  content: T; }  
let stringBox: Box<string> = { content: "hello" }; 
let numberBox: Box<number> = { content: 123 };

(3) 泛型类

class DataStore<T> {   private data: T[] = [];    add(item: T) {     this.data.push(item);   }    getAll(): T[] {     return this.data;   } 
}  
const stringStore = new DataStore<string>(); 
stringStore.add("hi"); 
stringStore.add("world"); 
console.log(stringStore.getAll());  // ["hi", "world"]

(4) 泛型约束 (extends)

有时你不希望 T 随便是什么类型,可以加 约束

注:这里的约束是,对象必须要有length属性

interface HasLength {   length: number; }  
function logLength<T extends HasLength>(item: T): void {  console.log(item.length); }  logLength("hello");   // ✅ string 有 length 
logLength([1, 2, 3]); // ✅ array 有 length// logLength(123);    // ❌ number 没有 length

(5) 多个泛型参数

function pair<K, V>(key: K, value: V): [K, V] {   return [key, value]; } 
let result = pair("id", 123);   // 类型: [string, number]

  1. 泛型的好处
  • 复用性强:不用为每个类型都写一个函数/类

  • 类型安全:比 any 更安全,保留了类型信息

  • 自动推断:减少手写类型的负担


✅ 总结一句话:
泛型就是类型的参数化,让代码既灵活又安全。

结构化的类型系统(structural type system)

TypeScript 的一个核心原则是类型检查基于对象的属性和行为(type checking focuses on the shape that values have)。这有时被叫做“鸭子类型”或“结构类型”(structural typing)。

在结构化的类型系统当中,如果两个对象具有相同的结构,则认为它们是相同类型的。


interface Point {    x: number;   y: number;  }  
function logPoint(p: Point) {    console.log(`${p.x}, ${p.y}`);  
}  // 打印 "12, 26"  const point = { x: 12, y: 26 };  
logPoint(point);

point 变量从未声明为 Point 类型。 但是,在类型检查中,TypeScript 将 point 的结构与 Point的结构进行比较。它们的结构相同,所以代码通过了。

结构匹配只需要匹配对象字段的子集。


const point3 = { x: 12, y: 26, z: 89 };  
logPoint(point3); // 打印 "12, 26"  const rect = { x: 33, y: 3, width: 30, height: 80 };  
logPoint(rect); // 打印 "33, 3"  const color = { hex: "#187ABF" };  
logPoint(color);  //这里会报错
//Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'.   Type '{ hex: string; }' is missing the following properties from type 'Point': x, y

类和对象确定结构的方式没有区别:

interface Point {    x: number;    y: number;  }  
function logPoint(p: Point) {    console.log(`${p.x}, ${p.y}`);  }  // ---分割线---  class VirtualPoint {    x: number;   y: number;    constructor(x: number, y: number) {     this.x = x;      this.y = y;    }  
}  
const newVPoint = new VirtualPoint(13, 56);  
logPoint(newVPoint); // 打印 "13, 56"

如果对象或类具有所有必需的属性,则 TypeScript 将表示是它们匹配的,而不关注其实现细节。

手册阅读

基础

静态类型检查

静态类型系统描述了程序运行时值的结构和行为。像 TypeScript 这样的静态类型检查器会利用类型系统提供的信息,并在事态发展不对劲的时候告知我们。

在这里插入图片描述

图中的上面是js,并不会报错;下面是ts,会显示错误。

非异常失败

  1. 当没有属性的时候,js会返回undefined,而ts会直接报错
    在这里插入图片描述

比如这里的错误,ts会显示没有该函数。
在这里插入图片描述

函数调用

这里函数调用的失败


function flipCoin() {
// 应该是 Math.random()
return Math.random < 0.5;// Operator '<' cannot be applied to types '() => number' and 'number'.
}

同时一些基本逻辑的错误,也会显示。

·

类型工具

TypeScript 可以在我们的代码出现错误时捕获 bug。这很好,但更关键的是,它能够在一开始就防止我们的代码出现错误。类型检查器可以通过获取的信息检查我们是否正在访问变量或者其它属性上的正确属性。一旦它获取到了这些信息,它也能够提示你可能想要访问的属性。这意味着 TypeScript 也能用于编辑代码。我们在编辑器中输入的时候,核心的类型检查器能够提供报错信息和代码补全。人们经常会谈到 TypeScript 在工具层面的作用,这就是一个典型的例子。

ts转换成js时

  1. 擦除类型(参数的类型注解不见)

  2. 降级(类似这样将更新或者“更高”版本的 ECMAScript 向下降级为更旧或者“更低”版本的代码,就是所谓的降级。)

  3. 严格性(开发者可以自己调节)

    1. noImplicitAny

      回想一下,在前面的某些例子中,TypeScript 没有为我们进行类型推断,这时候变量会采用最宽泛的类型:any。这并不是一件最糟糕的事情 —— 毕竟,使用 any 类型基本就和纯 JavaScript 一样了。
      但是,使用 any 通常会和使用 TypeScript 的目的相违背。你的程序使用越多的类型,那么在验证和工具上你的收益就越多,这意味着在编码的时候你会遇到越少的 bug。启用 noImplicitAny 配置项,在遇到被隐式推断为 any 类型的变量时就会抛出一个错误

    2. strictNullChecks

      默认情况下,nullundefined 可以被赋值给其它任意类型。这会让你的编码更加容易,但世界上无数多的 bug 正是由于忘记处理 nullundefined 导致的 —— 有时候它甚至会带来数十亿美元的损失!strictNullChecks 配置项让处理 nullundefined 的过程更加明显,让我们不用担心自己是否忘记处理 nullundefined

基本类型

any: 这个数据类型,可以向里面塞任何东西,或者当成函数调用,ts都不会报错。但在写代码的时候,避免使用这种数据类型,因为不安全。

注:当数据没有被指明数据类型时,并且编译器不能从上下文推断出变量的类型时,编译器会默认数据类型为any

函数:可以声明参数类型和返回值类型,同时使用箭头函数或者匿名函数时,参数的类型ts会利用上下文进行推断

对象

对象的属性如果没有声明其类型,默认值也是any

属性可以是全部,也可以是部分,只需要一个?
如果有属性没有传递,那么该属性的是 undefined 的状态

function printName(obj: {first:string,last?:string}){//...if(obj.last !== undefined){console.log(obj.latt.toUpperCase());}// A safe alternative using modern JavaScript syntax:console.log(obj.last?.toUpperCase());
}printName({first:"John",last:"Doe"});
printName({first:"Jane"});

Union Type

Defining a Union Type

The first way to combine types you might see is a union type. A union type is a type formed from two or more other types, representing values that may be any one of those types. We refer to each of these types as the union’s members.

Let’s write a function that can operate on strings or numbers:

function printID(id: number | string){console.log(`ID is ${id}`);
}printID(123);
printID("456");

if the id type is not number or string,it will throw an error.

注:

  1. TypeScript will only allow you to do things with the union if that thing is valid for every member of the union. For example, if you have the union string | number, you can’t use methods that are only available on string: --> 变量调用的方法必须满足联合体里面的所有类型

解决方案:Narrowing 联合体,例子如下

function printId(id: number | string) {if (typeof id === "string") {// In this branch, id is of type 'string'console.log(id.toUpperCase());} else {// Here, id is of type 'number'console.log(id);}
}
  1. 如果联合体成员的所有成员类型都有这个方法,就不需要缩小narrowing联合体

重命名

  1. 在下面这个示例中,我们将一个对象取名为Point了
type Point = {x: number;y: number;
}function drawPoint(point: Point){console.log(`(${point.x},${point.y})`);
}
drawPoint({x:10,y:20});
  1. 类型别名可以为任何类型重命名,比如联合体
type ID = number | string;
  1. type 这个关键字z在TypeScript 中不会产生新类型,只是原类型的别名

接口

接口声明 是命名对象类型的另一种方式:

interface Point {    x: number;    y: number;  }  function printCoord(pt: Point) {   console.log("The coordinate's x value is " + pt.x);    console.log("The coordinate's y value is " + pt.y);  
}  printCoord({ x: 100, y: 100 });

就像我们上面使用类型别名时一样,这个示例的工作方式就像我们使用了匿名对象类型一样。 TypeScript 只关心我们传递给 printCoord 的值的结构 - 它只关心它是否具有预期的属性。 只关心类型的结构和功能,这就是为什么我们说 TypeScript 是一个 结构化类型 的类型系统。

typed 和 接口之间的区别

类型别名和接口非常相似,在大多数情况下你可以在它们之间自由选择。 几乎所有的 interface 功能都可以在 type 中使用,关键区别在于不能重新开放类型以添加新的属性,而接口始终是可扩展的。

![[Pasted image 20251004174033.png]]

Type Assertions

Type Assertions(类型断言) = 告诉 TypeScript 编译器一个值具体是什么类型

let someValue: unknown = "Hello World";
let strLength: number = (someValue as string).length;
  • 用法:value as Type
  • 常用于 DOM 操作、联合类型缩小、绕过编译器类型不确定时的报错。
  • 不会改变运行时的值,只是编译器检查时的“强制声明”。

注:Like a type annotation, type assertions are removed by the compiler and won’t affect the runtime behavior of your code.

字面量

  1. 基本说明
let x: "hello" = "hello";
// OK
x = "hello";// ...
//Type '"howdy"' is not assignable to type '"hello"'.
x = "howdy";
  1. 字面量和联合体结合
function printText(s: string, alignment: "left" | "right" | "center") {// ...
}printText("Hello, world", "left");
printText("G'day, mate", "centre");
//Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
  1. 更多说明

interface Options {width: number;
}function configure(x: Options | "auto") {// ...
}configure({ width: 100 });
configure("auto");
configure("automatic");
//Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.
  1. 示例说明用法,结合类型断言

const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
//Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.

两种修改方式

  1. You can change the inference by adding a type assertion in either location:
   // Change 1:  const req = { url: "https://example.com", method: "GET" as "GET" };  // Change 2  handleRequest(req.url, req.method as "GET");

Change 1 means “I intend for req.method to always have the literal type "GET"”, preventing the possible assignment of "GUESS" to that field after. Change 2 means “I know for other reasons that req.method has the value "GET"“. —> 将 method 中进行一个类型断言,告诉编译器它的值是对的

  1. You can use as const to convert the entire object to be type literals:
const req = { url: "https://example.com", method: "GET" } as const;  
handleRequest(req.url, req.method);

The as const suffix acts like const but for the type system, ensuring that all properties are assigned the literal type instead of a more general version like string or number. —> 这样的const会将每一个属性都变成const;req前面的const只是req的指向不能改变

null and undefined

strictNullChecks off

With strictNullChecks off, values that might be null or undefined can still be accessed normally, and the values null and undefined can be assigned to a property of any type. This is similar to how languages without null checks (e.g. C#, Java) behave. The lack of checking for these values tends to be a major source of bugs; we always recommend people turn strictNullChecks on if it’s practical to do so in their codebase. —> 大多数的bug,都是由于它引起的,所以建议打开它

strictNullChecks on

With strictNullChecks on, when a value is null or undefined, you will need to test for those values before using methods or properties on that value. Just like checking for undefined before using an optional property, we can use narrowing to check for values that might be null: —> 可以使用缩小来判断null的发生,如果没有这个判断,编译器会报错

 function doSomething(x: string | null) {    if (x === null) {      // do nothing    } else {      console.log("Hello, " + x.toUpperCase());    }  
}

Non-null Assertion Operator (Postfix !)

TypeScript also has a special syntax for removing null and undefined from a type without doing any explicit checking. Writing ! after any expression is effectively a type assertion that the value isn’t null or undefined:

function liveDangerously(x?: number | null) {    // No error    console.log(x!.toFixed());  
}

Just like other type assertions, this doesn’t change the runtime behavior of your code, so it’s important to only use ! when you know that the value can’t be null or undefined. —> 告诉编译器,这个一定不是null 或者 undefined

JS补充内容

🔑 JavaScript 基本类型(原始类型)

  1. boolean

    • 布尔类型,只有两个值:truefalse
    • 例子:
      let isLogin = true; let finished = false;
  2. number

    • 数字类型,包括整数和浮点数(JS 中没有单独的整数类型)。
    • 还包括一些特殊值:NaN(不是数字)、Infinity(无穷大)、-Infinity
    • 例子:
      let age = 25; let price = 9.99; let notANumber = NaN; let max = Infinity;
  3. **`bigint

    • 表示任意精度的整数,可以处理超大数字。
    • n 结尾来表示:
      let big = 123456789012345678901234567890n;
  4. string

    • 字符串类型,用于文本。
    • 可以用 '单引号'"双引号"`反引号`(模板字符串)。
    • 例子:
      let name = "Alice"; let greet = `Hello, ${name}!`;
  5. symbol

    • ES6 引入,表示一个唯一的值,常用于对象的属性键。
    • 例子:
      let id = Symbol("id"); let obj = { [id]: 123 };
  6. null

    • 表示“空值”,即有意让变量没有值
    • 通常用来表示某个值暂时不存在
    • 例子:
      let user = null;
  7. undefined

    • 表示“未定义”,通常是变量声明了但还没有赋值时的默认值。
    • 例子:
      let x; console.log(x); // undefined
http://www.dtcms.com/a/442749.html

相关文章:

  • 上海建设银行官方网站有关网站排名的论文
  • Zabbix对决Prometheus:监控系统终极对比
  • 【ROS2学习笔记】 TF 坐标系
  • 如何给网站绑定域名邢台推广公司
  • AgentLightning浅读
  • 友情链接对网站的作用喜茶vi设计手册
  • 开通企业网站需要多少钱wordpress添加m3u8播放器
  • 广义可逆计算 (Generalized Reversible Computation): 一个软件构造范式的正名与阐释
  • js网站开发视频教程北京自己怎样做网站
  • 稠密检索模型(Dense Retrieval Model)
  • 东莞网站建设员天长网站制作
  • 【精品资料鉴赏】361页word详解绿色智慧校园建设方案
  • 深圳哪家网站建设公司好万江仿做网站
  • 爱空间网站模板淘宝网官方网
  • 在云服务器中下载和使用Navicat连接mysql数据库
  • 优化算法研究Beale函数
  • 用万网做网站龙岗网站建设公司
  • roboguide如何显示或关闭寄存器或 IO 的注释信息
  • 公司电商网站开发方案数学网站建设方法
  • 网站开发与设计实训报告心得营销型网站建设的目标是
  • 建网站没有公司资质wordpress 下载远程图片
  • 网站建设与管理课程的目标织梦+和wordpress
  • 上国外网站哪个dns快网站查询平台官网
  • wordpress建站环境国内网络科技网站建设
  • 2025年渗透测试面试题总结-101(题目+回答)
  • 免费做网站. 优帮云上海公司招聘信息
  • K8s集群CNI升级:Calico3.28.2安装全攻略
  • 常州市城乡建设局网站网站内容和功能清单
  • 网站美工承德信息网络有限公司
  • 全星质量管理 QMS 软件系统:汽车电子与芯片半导体行业的 “质量一体化管家”