【鸿蒙开发】TypeScript语言1:数据类型和接口

鸿蒙HarmonyOS NEXT开发之路 卷1:ArkTS语言篇 在数字化浪潮的推动下,全球科技领域正经历着前所未有的变革。我国作为这一变革的积极参与者,不仅在多个科技前沿领域取得了显著成就,更在计算机操作系统这一核心技术领域孕育出了具有自主知识产权的创新成果—鸿蒙系统(HarmonyOS)。这一系统开发成功不仅是国人的骄傲,更是全球技术竞争中的一股新兴力量。鸿蒙系统的诞生,标志着我国在全球操作系统领域迈出了坚实的一步。凭借其独特的分布式架构、跨平台能力以及对开发者友好的设计理念,它为智能设备带来了全新的使用体验。 阅读详情

ArkTS在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升代码健壮性,并实现更好的程序执行稳定性和性能。

所以,要想学号ArkTS得先了解TS。

在线编程:TS在线演练场

一、变量声明

在TypeScript中,使用let或const关键字来声明变量。let声明的变量可以被重新赋值,而const声明的变量则需要在声明时初始化,并且之后不能被重新赋值(对于对象或数组,这意味着不能改变它们的引用,但可以修改它们的属性或元素)。

变量后面可以跟随一个冒号和类型注解,来指定变量的类型。例如:

let hello = "Hello!";
const pp = 99;

变量命名规则:

  • 只能出现数字、字母、下划线、美元符号($)
  • 不能以数字开头
  • TS区分大小写
    推荐使用驼峰命名法进行变量命名。

类型推断:
TS会在没有明确的指定类型的时候推测出一个类型:

  • 定义变量时赋值了, 推断为字面量对应的类型
  • 定义变量时没有赋值, 推断为 any 类型

二、 数据类型

TypeScript 中的数据类型分为了两大类:基本数据类型(原始数据类型)和复杂数据类型(对象类型)

TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

类型表示说明
布尔类型booleantrue false
数值类型number123 1.23
字符串类型string"abc" 'abc'
null/undefined类型null / undefined表示null和undefined本身,意义不大
任意类型any没有指定任何类型
数组类型Type[]number[] string[]
联合类型number | string一个值可以是几种类型之一
字面量类型'left' | 'center' | 'right'限制变量或参数的取值,只能是其中之一
函数类型() => void对函数的参数及返回值指定类型
对象类型{…}限定对象的结构(属性及方法)
复杂类型interface接口
泛型<T>

在TypeScript中,类型系统基于JavaScript并进行了扩展,可分为原生类型(JavaScript固有的基础类型,TypeScript直接继承并增强)和特殊类型(TypeScript特有的、用于类型系统增强的类型)。

以下是TypeScript中原生类型和特殊类型的表格整理:

1、原生类型(JavaScript 基础类型,TypeScript 直接支持)

类型名称描述示例
number表示所有数字(整数、浮点数、NaN、Infinity 等)let num: number = 3.14;
string表示文本字符串(单引号、双引号、模板字符串均可)let str: string = `Hello ${name}`;
boolean表示布尔值,仅包含 true 和 falselet flag: boolean = true;
null表示“空值”,单值类型(严格模式下需显式声明)let empty: null = null;
undefined表示“未定义”,变量未赋值时的默认值(严格模式下需显式声明)let unassigned: undefined = undefined;
symbolES6 引入的唯一标识符,通过 Symbol() 创建,值唯一const key: symbol = Symbol('id');
bigintES2020 引入的大整数类型,用于超出 number 精度范围的整数(后缀 n)let big: bigint = 9007199254740993n;
object表示非原始类型(除上述7种外的类型,如对象、数组、函数等)let obj: object = { name: 'Tom' };

2、特殊类型(TypeScript 特有,用于增强类型系统)

类型名称描述示例
any关闭类型检查,变量可赋值任意类型,可调用任意方法(不报错)let value: any = 'hello'; value = 123; value.toFixed();
unknown安全的“未知类型”,使用前需通过类型检查或断言确认类型let val: unknown = 'test'; if (typeof val === 'string') { val.length; }
void表示“无返回值”,常用于函数返回类型(可省略 return 或返回 undefined)function log(): void { console.log('hi'); }
never表示“永远不会发生的值”,用于函数永不正常结束的场景(如抛异常、死循环)function error(): never { throw new Error('fail'); }
元组(Tuple)固定长度、固定类型顺序的数组let user: [string, number] = ['张三', 18];
枚举(Enum)命名的常量集合,默认值从0递增(可手动指定)enum Direction { Up = 1, Down, Left, Right }
联合类型(Union)值可以是多种类型中的一种(用 | 分隔)let id: string | number = '123'; id = 456;
交叉类型(Intersection)同时具有多种类型的属性(用 & 合并)type A = { name: string }; type B = { age: number }; type C = A & B;
字面量类型(Literal)具体单值作为类型,只能取该值(常与联合类型结合限制取值范围)type Status = 'success' | 'error' | 'pending';

一、 各类型说明

2.1 布尔

最基本的数据类型就是简单的true/false值,在JavaScript和TypeScript里叫做boolean。

let isDone: boolean = false;

2.2 数值

和JavaScript一样,TypeScript里的所有数字都是浮点数。 这些浮点数的类型是 number。 除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。

let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

2.3 字符串

可以使用双引号( ")或单引号(')表示字符串。
也使用模版字符串,它可以定义多行文本和内嵌表达式。 这种字符串是被反引号包围(`),并且以${ expr }这种形式嵌入表达式.

let name: string = "bob";
name = "smith";

let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.

I'll be ${ age + 1 } years old next month.`;
//等价于下面:
let sentence: string = "Hello, my name is " + name + ".\n\n" +
    "I'll be " + (age + 1) + " years old next month.";

2.4 数组

两种声明方式

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

2.5 元组 Tuple

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
//当访问一个已知索引的元素,会得到正确的类型
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
//当访问一个越界的元素,会使用联合类型替代
x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型
console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toString
x[6] = true; // Error, 布尔不是(string | number)类型

2.6 枚举

enum类型是对JavaScript标准数据类型的一个补充。

enum Color {Red, Green, Blue}
let c: Color = Color.Green;
//默认情况下,从0开始为元素编号。 也可以手动的指定成员开始的数值。 
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
//或者,全部都采用手动赋值:
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
//枚举类型提供的一个便利是你可以由枚举的值得到它的名字。
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName);  // 显示'Green'因为上面代码里它的值是2

2.7 Any

有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any类型来标记这些变量。

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
//当你只知道一部分数据的类型时,any类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:
let list: any[] = [1, true, "free"];
list[1] = 100;

在对现有代码进行改写的时候,any类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。 你可能认为 Object有相似的作用,就像它在其它语言中那样。 但是 Object类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法

let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

2.8 Void

某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void

function warnUser(): void {
    console.log("This is my warning message");
}
//声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null:
let unusable: void = undefined;

2.9 Null 和 Undefined

undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大:

// 本身赋值没啥用
let u: undefined = undefined;
let n: null = null;

默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给number类型的变量。

然而,当你指定了--strictNullChecks标记,null和undefined只能赋值给void和它们各自。 这能避免 很多常见的问题。 也许在某处你想传入一个 string或null或undefined,你可以使用联合类型string | null | undefined。

2.10 Never

never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。

never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}

// 推断的返回值类型为never
function fail() {
    return error("Something failed");
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
    while (true) {
    }
}

2.11 Object、object 和 {}

在TypeScript中,Object、object 和 {} 看似相似,实则在类型约束和适用场景上有显著区别,主要体现在对“可赋值类型”的限制上。以下是具体对比:

类型定义与本质可赋值的类型(允许的值)禁止赋值的类型典型场景与注意事项
Object首字母大写,对应JavaScript中原生的Object构造函数类型,代表“所有继承自Object.prototype的类型”(包括原始类型的包装对象)。- 所有对象类型(普通对象、数组、函数等)
- 所有原始类型(number、string、boolean等,因为它们会被“装箱”为包装对象,如Number、String)
- null和undefined在非严格模式下可赋值(严格模式下禁止)。
无(几乎所有值都能赋值,因为原始类型会被隐式装箱为对象)过于宽泛,几乎失去类型约束意义,不推荐使用。除非明确需要兼容所有“继承自Object”的类型。
object小写,TypeScript 2.2新增,代表“非原始类型”(即排除所有原始类型的值)。- 所有对象类型(普通对象{}、数组[]、函数() => {}、日期Date等)
- 不包括原始类型的包装对象(如new Number(123)本质是对象,可赋值)。
- 所有原始类型(number、string、boolean、symbol、bigint)
- null和undefined(严格模式下)。
用于明确限制“必须是非原始类型”的场景,比Object更严格,推荐使用(如函数参数需传入对象而非原始值时)。
{}空对象类型,代表“没有自有属性,但可继承Object.prototype方法的对象”(如toString、hasOwnProperty等)。- 空对象{}
- 所有原始类型(同Object,因装箱后有继承的方法)
- 非空对象(但访问其自有属性会报错,因为{}未声明这些属性)。
- null和undefined(严格模式下)。表示“一个空对象”,但允许原始类型赋值(因装箱特性)。不推荐直接使用,如需空对象建议用更严格的Record<string, never>。
关键区别示例:
// 1. Object 类型:允许原始类型和对象类型
const a: Object = 123; // 合法(123被装箱为Number对象)
const b: Object = 'hello'; // 合法(装箱为String对象)
const c: Object = { name: 'Tom' }; // 合法
const d: Object = () => {}; // 合法


// 2. object 类型:仅允许非原始类型(对象、数组、函数等)
const e: object = 123; // 报错(123是原始类型)
const f: object = 'hello'; // 报错(原始类型)
const g: object = { name: 'Tom' }; // 合法
const h: object = [1, 2, 3]; // 合法(数组是非原始类型)
const i: object = () => {}; // 合法(函数是非原始类型)


// 3. {} 类型:允许原始类型(装箱后)和空对象,但访问自有属性会报错
const j: {} = 123; // 合法(装箱后有继承方法)
const k: {} = { name: 'Tom' }; // 合法(但访问k.name会报错,因为{}未声明name属性)
const l: {} = {}; // 合法(空对象)
l.age = 18; // 报错({}类型不允许添加自有属性)

总结:

  • Object:最宽泛,兼容所有原始类型(装箱后)和对象类型,几乎无约束,不推荐。
  • object:严格限制为“非原始类型”,适合需要明确排除原始值的场景,推荐使用。
  • {}:表示“无自有属性的对象”,但仍兼容原始类型(装箱后),约束较弱,不推荐直接使用(建议用更具体的类型)。

实际开发中,应优先使用具体的对象类型(如{ name: string }、number[])而非这三种宽泛类型,以提升类型安全性。

详解{ name: string }
{ name: string } 属于 TypeScript 中的 对象字面量类型(Object Literal Type),是一种具体的对象类型,用于精确描述对象的结构(即对象应包含的属性及其对应类型)。

特点:

  1. 结构约束:明确规定对象必须包含 name 属性,且该属性的类型必须是 string。

    • 例如:const user: { name: string } = { name: 'Alice' }; 是合法的(符合结构)。
    • 若缺少 name 属性(如 { age: 18 })或 name 类型不符(如 { name: 123 }),会触发类型错误。
  2. 扩展性:默认情况下,对象字面量类型是“精确匹配”的,不允许多余的未声明属性(除非开启 suppressExcessPropertyErrors 配置,但不推荐)。
    例如:const user: { name: string } = { name: 'Bob', age: 20 }; 会报错(age 是多余属性)。

  3. 匿名与命名:{ name: string } 本身是匿名的对象字面量类型,可通过 type 或 interface 命名复用:

    type User = { name: string }; // 命名为 User 类型
    interface IUser { name: string }; // 接口形式(功能类似,细微差异)
    
与其他对象类型的区别:
  • 不同于宽泛的 object 类型(泛指所有非原始类型),{ name: string } 是精确的结构描述,提供更强的类型约束。
  • 不同于 {}(空对象类型,允许原始类型装箱后赋值),{ name: string } 严格限制对象必须包含指定属性。

简单说,{ name: string } 是对“具有 name 字符串属性的对象”的类型定义,是 TypeScript 中描述对象结构最常用的方式之一。

对象的声明

在TypeScript中,创建对象的声明方式主要围绕“类型约束”展开,既可以直接使用对象字面量,也可以通过类型定义(如接口、类型别名)复用结构,还可以通过类实例化等方式。以下是常见的声明方式及示例:

1. 对象字面量(直接声明,带或不带类型注解)

最基础的方式,直接定义对象并可选地添加类型注解(明确对象结构)。

  • 无类型注解:TypeScript会自动推断对象类型(根据属性值)。
  • 带类型注解:显式指定对象的属性及类型,强制约束结构。
// 1.1 无类型注解(自动推断)
const user = {
  name: "Alice",
  age: 25,
  isStudent: false
};
// 推断类型:{ name: string; age: number; isStudent: boolean }


// 1.2 带类型注解(显式约束)
const user: { 
  name: string; 
  age: number; 
  isStudent?: boolean; // 可选属性(可省略)
} = {
  name: "Bob",
  age: 30
  // isStudent 可省略(因是可选属性)
};

特点:适合简单、一次性的对象,无需复用类型时使用。

2. 通过接口(interface)声明

接口(interface)用于定义对象的“结构契约”,可复用且支持继承,适合描述复杂对象类型。

// 定义接口(描述对象结构)
interface User {
  name: string;
  age: number;
  readonly id: string; // 只读属性(初始化后不可修改)
  sayHello?: () => void; // 可选方法
}

// 使用接口声明对象
const user1: User = {
  name: "Charlie",
  age: 28,
  id: "u123",
  sayHello: () => console.log("Hello")
};

const user2: User = {
  name: "Diana",
  age: 22,
  id: "u124"
  // 可省略可选方法 sayHello
};

特点:

  • 支持合并声明(同一接口多次定义会自动合并);
  • 可被类实现(class XXX implements User);
  • 适合团队协作中复用对象结构。
3. 通过类型别名(type)声明

类型别名(type)通过type关键字为对象类型命名,功能类似接口,但更灵活(可描述联合类型、交叉类型等)。

// 定义类型别名(描述对象结构)
type Product = {
  id: number;
  name: string;
  price: number;
};

// 使用类型别名声明对象
const phone: Product = {
  id: 1,
  name: "Phone",
  price: 5999
};

// 类型别名支持联合/交叉类型(接口不支持)
type CartItem = Product & { quantity: number }; // 交叉类型(合并Product和quantity)
const cartItem: CartItem = {
  id: 1,
  name: "Phone",
  price: 5999,
  quantity: 2
};

特点:

  • 不可合并声明(重复定义会报错);
  • 支持更复杂的类型组合(联合、交叉等);
  • 适合一次性定义复杂对象结构。
4. 通过类(class)实例化对象

类(class)用于创建“具有相同属性和方法的对象模板”,通过new实例化对象,类的类型会自动约束实例结构。

// 定义类(包含属性和方法)
class Animal {
  name: string; // 实例属性(需显式类型)
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  bark(): void {
    console.log(`${this.name} is barking`);
  }
}

// 实例化对象(自动符合类的类型)
const dog = new Animal("Buddy", 3);
dog.bark(); // "Buddy is barking"

特点:

  • 包含属性和方法,适合需要“行为”的对象;
  • 支持继承(extends)和访问修饰符(public/private/protected)。
5. 索引签名(处理动态属性的对象)

当对象属性名不固定(动态生成)时,使用索引签名(字符串/数字索引)声明对象类型。

// 字符串索引签名:键为string,值为number(如字典)
type NumberDict = {
  [key: string]: number;
};
const scores: NumberDict = {
  math: 90,
  english: 85,
  // 动态添加的属性也必须符合类型
  chinese: 95
};

// 数字索引签名:键为number,值为string(如数组-like对象)
type StringArray = {
  [index: number]: string;
  length: number; // 显式属性(与索引类型无关)
};
const arr: StringArray = {
  0: "a",
  1: "b",
  length: 2
};

特点:适合属性名动态变化的场景(如字典、配置对象)。

6. 匿名类型与类型断言

对于临时对象,可直接使用匿名类型;若TypeScript推断类型不准确,可通过类型断言(as)手动指定。

// 匿名类型(直接在变量后写类型结构)
const config: {
  env: "dev" | "prod";
  port: number;
} = {
  env: "dev",
  port: 3000
};

// 类型断言(当类型推断不符合预期时)
const data: unknown = { id: 1, name: "Test" };
const item = data as { id: number; name: string }; // 断言为目标类型

特点:匿名类型适合临时场景;类型断言用于“告诉TS实际类型”(需确保正确性,否则有风险)。

还有let a = <InterfaceName>{} 这种 TypeScript 中的类型断言(Type Assertion) 声明方式。

具体解释:

  • <InterfaceName>{} 中的 <InterfaceName> 是类型断言的语法(另类型>值 的形式),作用是告诉编译器“该空对象 {} 应被视为 InterfaceName 类型”,强制指定对象的类型。
  • 这本质上是“手动告诉告诉 TypeScript 我比你更了解这个值的类型”,用于手动修正 TypeScript 的类型推断(但不会改变值的实际类型,仅影响类型检查)。

示例说明:
假设有一个接口 User:

interface User {
  name: string;
  age: number;
}

使用 <User>{} 断言空对象为 User 类型:

// 类型断言:将空对象 {} 断言为 User 类型
let a = <User>{}; 

// 此时 a 被编译器视为 User 类型,可以安全地添加属性(若不断言,直接给 {} 添加属性会报错)
a.name = "Alice";
a.age = 25;

与其他方式的区别:

  • vs 类型注解(let a: User = {}):
    类型注解(: 语法)是直接声明变量的类型约束,此时若赋值 {} 会报错(因为缺少 name 和 age 属性);
    而类型断言(<User>{})是“强制通过类型检查”,告诉编译器“虽然现在是空对象,但后续会符合 User 结构”,暂时不会报错(但需确保后续补全属性,否则可能导致运行时问题)。

  • 另一种断言语法(as):
    TypeScript 还支持 as 语法进行类型断言(与 <类型> 等价),更推荐在 JSX 中使用(避免与 JSX 标签冲突):

    let a = {} as User; // 与 <User>{} 效果完全一致
    

总结
不同声明方式的适用场景:

  • 简单、一次性对象:对象字面量;
  • 复用结构、团队协作:接口(interface);
  • 复杂类型组合(联合/交叉):类型别名(type);
  • 带行为(方法)的对象:类(class);
  • 动态属性对象:索引签名;
  • 临时对象或类型修正:匿名类型/类型断言。

根据对象的复杂度和复用需求选择合适的方式即可。

2.12 symbol

自ECMAScript 2015起,symbol成为了一种新的原生类型。过Symbol构造函数创建。

let sym1 = Symbol();
let sym2 = Symbol("key"); // 可选的字符串key
//Symbols是不可改变且唯一的。
let sym2 = Symbol("key");
let sym3 = Symbol("key");
sym2 === sym3; // false, symbols是唯一的
//像字符串一样,symbols也可以被用做对象属性的键
let sym = Symbol();
let obj = {
    [sym]: "value"
};
console.log(obj[sym]); // "value"

二、 解构和展开

1. 解构

最简单的解构莫过于数组的解构赋值了:

let input = [1, 2];
let [first, second] = input;
console.log(first); // outputs 1
console.log(second); // outputs 2
// 变量交换
[first, second] = [second, first];
// 函数参数
function f([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}
f(input);
// 数组里使用...语法创建剩余变量
let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // outputs 1
console.log(rest); // outputs [ 2, 3, 4 ]
// 忽略不关心的尾随元素
let [first] = [1, 2, 3, 4];
console.log(first); // outputs 1
// 忽略某些元素
let [, second, , fourth] = [1, 2, 3, 4];
// 对象解构
let o = {
    a: "foo",
    b: 12,
    c: "bar"
};
let { a, b } = o; // c是可忽略的
//无声明赋值
({ a, b } = { a: "baz", b: 101 }); // 注意,我们需要用括号将它括起来,因为Javascript通常会将以 { 起始的语句解析为一个块。
//对象里使用...语法创建剩余变量
let { a, ...passthrough } = o;
let total = passthrough.b + passthrough.c.length;

// 属性重命名
let { a: newName1, b: newName2 } = o; // 这里冒号不是指示类型的。
// 等价于
let newName1 = o.a;
let newName2 = o.b;
// 如果你想指定它的类型, 仍然需要在其后写上完整的模式
let {a, b}: {a: string, b: number} = o;

// 模仿对象参数默认值
function keepWholeObject(wholeObject: { a: string, b?: number }) {
    let { a, b = 1001 } = wholeObject; // 反直觉。即使wholeObject 的 b 为 undefined ,a,b都会有值。注意,wholeObject.b还是undefined 
}
// 对比基础类型默认值,必选参数(age)在前,默认值参数(name)在后
function introduce(age: number, name: string = "Anonymous") {
  console.log(`I'm ${name}, ${age} years old.`);
}

// 解构用于函数声明
type C = { a: string, b?: number }
function f({ a, b }: C): void {
    // ...
}


在这里插入图片描述

2. 展开

展开操作创建的一份浅拷贝
对象后面的属性会覆盖前面的属性。

// 展开数组
let first = [1, 2];
let second = [3, 4];
let bothPlus = [0, ...first, ...second, 5]; //[0, 1, 2, 3, 4, 5]
// 展开对象
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { ...defaults, food: "rich" }; // { food: "rich", price: "$$", ambiance: "noisy" }
let search = { food: "rich", ...defaults }; //  { food: "spicy", price: "$$", ambiance: "noisy" }

// 丢失对象方法
class C {
  p = 12;
  m() {
  }
}
let c = new C();
let clone = { ...c };
clone.p; // ok
clone.m(); // error!

对象展开还有其它一些意想不到的限制:

  1. 它仅包含对象 自身的可枚举属性。 大体上是说当你展开一个对象实例时,你会丢失其方法.
  2. TypeScript编译器不允许展开泛型函数上的类型参数。 这个特性会在TypeScript的未来版本中考虑实现。

三、 类型断言

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。
类型断言有两种形式。

//方式1
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length; // <string>someValue部分属于类型断言
//方式2
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

三、 接口

TypeScript的核心原则之一是对值所具有的结构进行类型检查。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label);
}
let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

// 使用接口改写
interface LabelledValue {
  label: string;
}
function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必需的属性是否存在,并且其类型是否匹配。
类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。

1. 可选属性

interface SquareConfig {
  color?: string; // 可选
  width?: number; // 可选
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {   // if (config.clor) {    // Error: Property 'clor' does not exist on type 'SquareConfig'
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

可选属性的好处之一是可以对可能存在的属性进行预定义,
好处之二是可以捕获引用了不存在的属性时的错误。

2. 只读属性

一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性:

interface Point {
    readonly x: number;
    readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

ypeScript具有ReadonlyArray类型,它与Array相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!
a = ro as number[]; // ok,可以用类型断言重写

readonly vs const

最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用readonly。

3. 额外的属性检查

不用细究,如果想直接通过字面量赋值给函数参数,则需要严格遵守接口要求。如果想接口宽松一点,可在接口中通过增加[name: type1]: type2;定义额外变量说明。从后面索引类型可知,type1只能是数字和字符串类型


interface SquareConfig {
    color?: string; // 对于额外的类型检查,参数可选和必选结果一样
    width?: number;
}
function createSquare(config: SquareConfig): { color: string; area: number } {
    // ...
}
let mySquare = createSquare({ colour: "red", width: 100 }); // error: 'colour' not expected in type 'SquareConfig'
// 通过变量中转,避开额外的属性检查
let tmp= { colour: "red", width: 100 };
let mySquare = createSquare(tmp); // ok

// 宽松接口
interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any; // 添加一个字符串索引签名,前提是你能够确定这个对象可能具有某些做为特殊用途使用的额外属性
}

4. 接口描述可索引的类型

interface StringArray {
  [index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];

// 可设置为只读
interface ReadonlyStringArray {
    readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!

TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型.
这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。

在TypeScript中,索引签名(Index Signatures)用于描述通过索引访问对象属性时的类型约束(例如 obj[key] 或 arr[index])。它允许我们定义“未知属性名但已知属性类型”的对象结构,常见于动态属性场景(如字典、数组等)。

TypeScript支持两种索引签名:字符串索引签名和数字索引签名,二者的核心区别在于“索引的类型”,但因JavaScript的特性(数字索引会被隐式转为字符串),同时使用时需遵守严格的兼容性规则。

1. 字符串索引签名(String Index Signatures)

通过字符串类型的索引(如 obj["name"])访问对象属性时,约束属性的类型。
语法:{ [key: string]: 类型 },其中 key 是任意合法的标识符(仅作为占位符,可自定义,如 prop、index 等)。

作用:规定“所有通过字符串索引访问的属性”必须符合指定类型,包括对象的显式属性(如 obj.name 本质是 obj["name"] 的语法糖)。

示例:

// 字符串索引签名:所有属性值必须是 string 类型
interface StringDict {
  [key: string]: string; 
  // 显式属性也必须符合索引签名类型(name 是 string,合法)
  name: string; 
}

const dict: StringDict = {
  name: "Alice",
  age: "25", // 合法:age 是字符串索引,值为 string
};

console.log(dict["name"]); // "Alice"(符合 string 类型)
console.log(dict.age); // "25"(等价于 dict["age"],合法)

注意:

  • 显式声明的属性类型必须与字符串索引签名的类型一致(否则报错)。例如,若添加 age: number,会因 number 与 string 不兼容报错。
  • 字符串索引签名适用于“键为字符串的对象”(如普通对象、字典)。
2. 数字索引签名(Numeric Index Signatures)

通过数字类型的索引(如 arr[0])访问对象属性时,约束属性的类型。
语法:{ [index: number]: 类型 },其中 index 是占位符(可自定义)。

作用:规定“所有通过数字索引访问的属性”必须符合指定类型,常见于数组、类数组对象(如 arguments)。

示例:

// 数字索引签名:所有数字索引访问的属性值必须是 number 类型
interface NumberArray {
  [index: number]: number;
}

const arr: NumberArray = [1, 2, 3]; 
console.log(arr[0]); // 1(符合 number 类型)
arr[1] = 4; // 合法:数字索引赋值为 number

// 类数组对象(如 DOM 集合)
interface NodeListLike {
  [index: number]: HTMLElement;
  length: number; // 显式属性 length 是 number(与数字索引类型无关)
}

注意:

  • 数字索引签名的“索引”本质是数字,但在JavaScript中,数字索引会被隐式转换为字符串(例如 arr[0] 等价于 arr["0"])。
  • 显式属性(如数组的 length)的类型无需与数字索引类型一致(length 是 number,与索引值的 number 只是巧合,非强制)。
同时使用两种索引签名的注意事项

当一个对象同时声明字符串索引签名和数字索引签名时,需满足数字索引的返回类型必须是字符串索引返回类型的子类型。

这是因为:在JavaScript中,数字索引会被自动转为字符串索引(例如 obj[0] 等价于 obj["0"])。因此,obj[0] 的类型(数字索引返回类型)必须兼容 obj["0"] 的类型(字符串索引返回类型),否则会出现类型矛盾。

1. 正确示例(数字索引类型是字符串索引类型的子类型)
interface CompatibleIndex {
  // 字符串索引:返回类型为 string | number(父类型)
  [key: string]: string | number;
  // 数字索引:返回类型为 number(是 string | number 的子类型,兼容)
  [index: number]: number;
}

const obj: CompatibleIndex = {
  "0": "hello", // 字符串索引 "0" 对应 string(符合 string | number)
  0: 123, // 数字索引 0 对应 number(符合数字索引类型,且与 "0" 的 string 兼容)
  name: "Alice", // 字符串索引 "name" 对应 string(合法)
  age: 25, // 字符串索引 "age" 对应 number(合法)
};

console.log(obj[0]); // 123(数字索引,返回 number)
console.log(obj["0"]); // "hello"(字符串索引,返回 string)
// 二者类型分别为 number 和 string,均兼容 string | number,无矛盾
2. 错误示例(数字索引类型与字符串索引类型不兼容)
interface IncompatibleIndex {
  [key: string]: string; // 字符串索引:返回类型为 string
  [index: number]: number; // 错误!number 不是 string 的子类型
}
// TypeScript 报错:
// 数字索引类型 'number' 不能赋给字符串索引类型 'string'

原因:obj[0](数字索引)返回 number,但它等价于 obj["0"](字符串索引),而字符串索引要求返回 string,导致 number 与 string 冲突,因此不允许。

3. 其他注意事项
  • 显式属性需兼容字符串索引:若对象有显式属性(如 name: string),其类型必须与字符串索引签名的类型一致(与数字索引无关)。
    例如:

    interface Example {
      [key: string]: string;
      [index: number]: string; // 数字索引是 string 的子类型(兼容)
      length: number; // 错误!length 的类型 number 与字符串索引的 string 不兼容
    }
    
  • 索引签名的“只读”修饰符:可通过 readonly 限制索引签名为只读(不能通过索引赋值),两种索引签名可分别设置只读:

    interface ReadonlyIndex {
      readonly [key: string]: string; // 字符串索引只读
      readonly [index: number]: string; // 数字索引只读
    }
    const obj: ReadonlyIndex = { "0": "a", 0: "b" };
    obj[0] = "c"; // 错误:只读索引不能赋值
    

5. 接口描述函数类型

描述带有属性的普通对象外,接口也可以描述函数类型。

interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean { // ok,函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配
  let result = src.search(sub);
  return result > -1;
}

mySearch = function(src, sub) {// ok, 如果你不想指定类型,TypeScript的类型系统会推断出参数类型,因为函数直接赋值给了 SearchFunc类型变量
    let result = src.search(sub);
    return result > -1;
}

6. 接口描述类类型

TypeScript也能够用接口来明确的强制一个类去符合某种契约。
接口只类的公共部分, 它不会帮你检查类是否具有某些私有成员。

interface ClockInterface {
    currentTime: Date; // 属性
    setTime(d: Date); // 方法,需在类里实现它
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}
类静态部分与实例部分的区别

当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。当用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误。

// 报错
interface ClockConstructor {
    new (hour: number, minute: number);
}
class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

// 应该直接操作静态部分
interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

7. 接口继承接口

interface Shape {
    color: string;
}
interface Square extends Shape {
    sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

// 继承多个接口
interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

8. 混合类型

有时希望一个对象可以同时具有多种类型。
一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性。

interface Counter {
    (start: number): string; // todo: 待解释
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

9. 接口继承类

当接口继承了一个类类型时,它会继承类的成员但不包括其实现。
就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。
接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现。

当你有一个庞大的继承结构时这很有用,但要指出的是你的代码只在子类拥有特定属性时起作用。

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

// 错误:“Image”类型缺少“state”属性。
class Image implements SelectableControl {
    select() { }
}

class Location {

}

参考

-----TypeScript官方教程-----
-----ArkTS详细教程------
TypeScript官方教程(英文)
TypeScript 基础语法及使用
TypeScript 基本语法
TypeScript基础语法(详细版)
【前端知识】TypeScript语法介绍

鸿蒙App开发学习 - TypeScript编程语言全面开发教程(上) TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的一个超集,添加了静态类型和其他一些新特性。TypeScript 可以编译为普通的 JavaScript 代码,因此可以在任何支持 JavaScript 的地方运行,并且可以与现有的 JavaScript 代码无缝集成。 阅读详情

相关推荐

鸿蒙开发就业前景到底怎么样?

鸿蒙,作为华为自主研发的基于微内核的下一代操作系统,正在逐渐走进人们的视野。随着鸿蒙系统的不断发展和完善,越来越多的人开始关注鸿蒙开发这一领域,想要了解学习鸿蒙开发的就业前景如何。

m0_70749039的博客 1917

鸿蒙:TypeScript开发语言

类(class)是面向对象编程语言中的一个重要概念。面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个Person类,其对象可以有张三李四等等。id: number;

weixin_71403100的博客 6472

Python 爬虫:获取网页数据的 5 种方法

requests:适用于简单的静态网页抓取,易于使用。requestslxml:适合需要高效解析大规模网页内容的情况,支持 XPath 和 CSS 选择器。Selenium:适用于动态网页(JavaScript 渲染)的抓取,模拟浏览器行为获取动态数据。Scrapy:强大的爬虫框架,适合大规模的网页抓取任务,支持异步请求和高级功能。PyQuery:基于 jQuery 语法,适合快速开发,提供简洁的 CSS 选择器语法。

想看什么文章都可以私信给我,综合性博客。 5513

鸿蒙系统扫盲(五):再谈鸿蒙开发用什么语言?

ets的性能在正常情况下是无法比得过Java的执行效率,而在方舟编译器和毕昇编译器的特别优化下,可以取得更高地执行效率(据说是可以比肩IOS的),之所以选择ts作为开发语言,因为每一个系统都需要配套的生态软件才能长久,而Java需要拖一个JVM,会降低运行效率,而C++门槛比较高,所以选择了有一定开发者基数,没有版权问题,且还能通过编译器提高运行效率的语言,所以华为选择了TypeScript。

memoryjs的专栏 8281

Python 逆向解析知乎盐选反爬字体,实现内容精准还原

本文详细解析了知乎盐选内容的反爬字体机制,并提供了使用Python逆向解析WOFF字体文件的完整方案。通过fontTools库构建解码字典,实现乱码文本的精准还原,帮助开发者应对动态字体策略,同时强调法律与道德风险。

weixin_29268385的博客 1296

AI辅助游戏开发实战:Kimi K3提升Unity开发效率与代码质量

在游戏开发领域,有限状态机(FSM)是构建角色AI行为逻辑的核心设计模式,它通过定义明确的状态和转换条件,使游戏实体能够智能地响应环境变化。其原理在于将复杂的行为分解为离散的状态节点,并通过事件驱动状态切换,从而实现清晰、可维护的AI架构。这项技术的价值在于显著提升了游戏角色的行为真实感和开发效率,被广泛应用于NPC行为控制、角色动画管理、UI流程等场景。随着AI编程助手的兴起,开发者现在可以借助如Kimi K3这类工具,通过自然语言指令快速生成和优化FSM等复杂系统的代码框架,将更多精力投入到核心玩法与性

weixin_30430677的博客 408

初识基于鸿蒙系统(HarmonyOS)的App开发

网传鸿蒙系统的下一个版本不再支持安卓,这几天看了一遍基于鸿蒙系统的App开发,现在二刷,顺便写一些心得或笔记吧。

Winter的博客 3991

硅谷刷屏的ClawdBot,让Mac mini卖爆了!创始人爆料:一人开发、100% AI 写代码

这两天,个人 AI 助手 ClawdBot 席卷硅谷,国内外社交平台上全是关于它的讨论。 在试用后,网友们纷纷给出了很高的评价。“它是迄今为止最伟大的 AI 应用,相当于你 24 小时全天候专属 AI 员工。”Creator Buddy 创始人兼 CEO Alex Finn 盛赞道,“这就是他们 (Anthropic) 希望 Claude Cowork 呈现的样子。”

技术引领业务创新 1585

HarmonyOS鸿蒙开发入门 , ArkTS语言的了解

鸿蒙(即HarmonyOS,开发代号Ark,正式名称为华为终端鸿蒙智能设备操作系统软件)是由华为公司2012年以来开发的分布式操作系统,并于2019年8月正式发布。该系统利用“分布式”技术,将手机、电脑、平板、电视、汽车和智能穿戴等多款设备融合成一个“超级终端”,使用户便于操作和共享各种设备的资源。通过这篇博客,我会记录我在学习HarmonyOS语法遇到的重点和难点。

WDJ54068923的博客 1万+

《矩阵论》学习笔记(四):4.2 矩阵的QR分解

《矩阵论》学习笔记(四):4.2 矩阵的QR分解 文章目录《矩阵论》学习笔记(四):4.2 矩阵的QR分解一. Givens矩阵与Givens变换1.1. 概念与理解1.2. Givens矩阵求解方法二. Householder矩阵与Householder变换2.1. 概念与理解2.2. Householder矩阵求解方法2.3. Givens变换与Householder变换的关系三. 矩阵的QR...

shine的博客 3681

Exploring Automated Distractor Generation for Math Multiple-choice Questions via Large Language Mode

多项选择题(MCQ)在几乎所有级别的教育中都无处不在,因为它们易于管理、评分,并且是评估和实践中可靠的格式。MCQ最重要的方面之一是干扰因素,即旨在针对真实学生常见错误或误解的不正确选项。迄今为止,对于教师和学习内容设计师来说,制作高质量的干扰物的任务在很大程度上仍然是一个劳动和时间密集型的过程,其可扩展性有限。在这项工作中,我们研究了数学MCQ领域的自动干扰物生成任务,并探索了从上下文学习到微调的各种基于大型语言模型(LLM)的方法。

c_cpp_csharp的专栏 317

[鸿蒙开发实战篇]Flutter鸿蒙开发

Flutter是Google开发的UI工具包,用于构建美观、原生性能的移动、Web和桌面应用程序。单一代码库,多平台部署高性能渲染引擎丰富的组件库热重载开发体验强大的状态管理鸿蒙系统是华为开发的分布式操作系统,支持多种设备形态。分布式架构微内核设计统一开发语言跨设备协同安全可靠。

尽吾所能 分享永久免费知识 4075

Nvidia Jetson平台 JP4.2.1版本GStreamer视频采集异常问题调试记录

Nvidia Jetson平台GStreamer in JP4.2.1不能采集但是 v4l2-ctl和 ffmpeg能正常采集视频。

jzwjzw19900922的博客 2124

Harmony:关于鸿蒙系统的内容都总结在这里了

比如我定义了 这四个视图元素按照屏幕宽度四等分 的规则,那么在任何尺寸下,这四个视图元素都会四等分屏幕宽度,从而达到相同的设计效果,这种在ArkUI里称为:均分能力 / 布局。ArkUI的原子布局能力总共分为7种:均分能力拆行能力拉伸能力缩放能力延伸能力占比能力隐藏能力。

chuyouyinghe的专栏 1580

2、MOSFET基本物理效应及其BSIM4模型解析

本文深入探讨了MOSFET的基本物理效应及其在BSIM4模型中的数学表述,涵盖门和沟道的几何结构、温度依赖性、材料模型选项、阈值电压计算、以及其他关键物理效应如LDD电阻、有限电荷厚度、有效迁移率等。同时解析了机械应力、邻近效应及布局依赖效应对MOSFET性能的影响,并通过参数表和建模流程提供了精确建模的指导,旨在帮助读者优化MOSFET器件性能与可靠性。

purple的博客 566

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

鸿蒙HarmonyOS实战开发:TypeScript-基础类型【基础篇】

我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等

2401_84194030的博客 1686

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

现在学鸿蒙系统开发有前景吗?

在科技日新月异的今天,操作系统作为数字世界的基石,其重要性不言而喻。鸿蒙系统,作为华为倾力打造的分布式操作系统,自问世以来便备受瞩目。那么,对于想要投身科技行业的你来说,现在学鸿蒙系统开发有前景吗?

2401_82546228的博客 2575

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【鸿蒙学习笔记】鸿蒙开发探秘:深入解析ArkTS语言与应用开发

本文介绍了鸿蒙系统(HarmonyOS)及其核心开发语言ArkTS。鸿蒙系统是华为自主研发的分布式操作系统,支持多设备互联协同,适用于智能家居、智慧办公等多场景。ArkTS作为鸿蒙主力开发语言,基于TypeScript扩展,具备静态类型、声明式UI、响应式编程和跨平台等特点,可提高开发效率和代码质量。文章详细解析了ArkTS基础语法,包括变量与数据类型、函数定义、控制流语句以及面向对象编程的类定义等内容,为开发者快速上手鸿蒙应用开发提供了技术指导。

CodeSuc 的技术博客 2318

HarmonyOS(鸿蒙系统)体系

HarmonyOS(鸿蒙系统)体系 Harmonyos官网 HarmonyOS Developer HarmonyOS 鸿蒙系统|鸿蒙学堂 华为开发者联盟 华为鸿蒙系统_百度百科 一 HarmonyOS源码下载 OpenHarmony 源码获取查看https://device.harmonyos.com/cn/docs/start/get-code/oem_sourcecode_guide-0000001050769927 在HarmonyOS源码在码云gitee上,代码仓库地址:https://ope

许浑的博客 5410

鸿蒙HarmonyOS实战开发:TypeScript-接口【基础篇】

TypeScript的核心原则之一是对值所具有的结构进行类型检查。

2401_84194030的博客 1571

HarmonyOS 5 鸿蒙ArkTS语言深度解析与TypeScript迁移实战指南

效率up:类型安全砍掉调试半壁江山。性能boost:启动内存双双优化。质量升:运行时bug基本绝迹。协作顺:类型文档让新人上手飞快。

haolove527的专栏 6141

【鸿蒙 HarmonyOS】TypeScript开发语言

类(class)是面向对象编程语言中的一个重要概念。面向对象编程(Object-Oriented Programming,简称 OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个 Person类,其对象可以有张三、**李四**等等。id: number。

贵公子丶笔记 760

鸿蒙应用开发(第二章:开发语言)

HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScript 本身也是由另一门语言 JavaScript 扩展而来。因此三者的关系如下图所示类(class)是面向对象编程语言中的一个重要概念。

moments的博客 8056

【粉丝福利社】鸿蒙HarmonyOS 6应用开发:从零基础到App上线

移动互联网十几年来的科技创新层出不穷,以设备互联为特色的鸿蒙(HarmonyOS)系统可谓一大创举,承载着国内自主IT产业链的厚望。鸿蒙系统自诞生之日起便自带明星光环,吸引了越来越多的开发者投身鸿蒙生态建设。有别于Android系统采用Java+XML的传统App开发方式,基于HarmonyOS 6的鸿蒙App采用ArkTS语言编写App代码,采用ArkUI作为声明式UI的开发框架,极大地简化了App界面布局和业务逻辑的编码过程。

愚公智库 6万+

TypeScript 与 ArkTS 全面对比:鸿蒙生态下的语言演进

随着华为鸿蒙系统(HarmonyOS)的快速发展,其官方推荐的原生应用开发语言ArkTS正逐步进入主流开发者视野。作为基于演进而来的编程语言,ArkTS 并非简单的语法糖叠加,而是一次面向操作系统层级的深度重构——它融合了静态类型安全、声明式 UI、高性能编译优化与分布式能力,旨在构建真正意义上的“一次开发,多端部署”原生应用。本文将从设计目标、类型系统、UI 开发范式、性能机制、生态定位。

csdn_silent的博客 2872

鸿蒙-TypeScript语法

HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。注意:TypeScript 本身也是由另一门语言 JavaScript 扩展而来,它主要是在JavaScript的基础上添加了静态类型定义。因此三者的关系如下图所示。

2401_83335728的博客 2688
上一篇: 【Python】Pycharm 调试Debug必知
下一篇: 【AIGC】在 Claude Code 中打印 LLM 请求体:抓包与非抓包方法全解
Code_LT
博客等级 码龄10年 307粉丝 182原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值