@lppx/nlearn 1.1.12 → 1.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/demo/data-types/01-/345/237/272/347/241/200/347/261/273/345/236/213.js +157 -0
- package/dist/src/demo/data-types/02-/346/225/260/347/273/204/344/270/216/345/205/203/347/273/204.js +169 -0
- package/dist/src/demo/data-types/03-/345/257/271/350/261/241/347/261/273/345/236/213.js +180 -0
- package/dist/src/demo/data-types/04-/345/207/275/346/225/260/347/261/273/345/236/213.js +182 -0
- package/dist/src/demo/data-types/05-/351/253/230/347/272/247/347/261/273/345/236/213.js +220 -0
- package/dist/src/demo/data-types/06-/346/263/233/345/236/213/347/261/273/345/236/213.js +174 -0
- package/dist/src/demo/operators-expressions/01-/345/237/272/347/241/200/350/277/220/347/256/227/347/254/246.js +144 -0
- package/dist/src/demo/operators-expressions/02-/347/261/273/345/236/213/350/277/220/347/256/227/347/254/246.js +212 -0
- package/dist/src/demo/operators-expressions/03-/344/275/215/350/277/220/347/256/227/347/254/246.js +190 -0
- package/dist/src/demo/operators-expressions/04-/350/241/250/350/276/276/345/274/217/344/270/216/346/261/202/345/200/274.js +202 -0
- package/package.json +1 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript 基础数据类型
|
|
4
|
+
* =====================
|
|
5
|
+
* 本文件介绍 TypeScript 的基础数据类型,包括:
|
|
6
|
+
* - 原始类型(number, string, boolean)
|
|
7
|
+
* - null 和 undefined
|
|
8
|
+
* - symbol 和 bigint
|
|
9
|
+
*
|
|
10
|
+
* 适用版本:TypeScript 5.x
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.demonstrateNumberType = demonstrateNumberType;
|
|
14
|
+
exports.demonstrateStringType = demonstrateStringType;
|
|
15
|
+
exports.demonstrateBooleanType = demonstrateBooleanType;
|
|
16
|
+
exports.demonstrateNullAndUndefined = demonstrateNullAndUndefined;
|
|
17
|
+
exports.demonstrateSymbolType = demonstrateSymbolType;
|
|
18
|
+
exports.demonstrateBigIntType = demonstrateBigIntType;
|
|
19
|
+
// #region 示例1: 数字类型 (number)
|
|
20
|
+
function demonstrateNumberType() {
|
|
21
|
+
console.log('\n=== 数字类型示例 ===');
|
|
22
|
+
// 整数
|
|
23
|
+
const integer = 42;
|
|
24
|
+
console.log('整数:', integer);
|
|
25
|
+
// 浮点数
|
|
26
|
+
const float = 3.14;
|
|
27
|
+
console.log('浮点数:', float);
|
|
28
|
+
// 十六进制
|
|
29
|
+
const hex = 0xff;
|
|
30
|
+
console.log('十六进制 0xff:', hex);
|
|
31
|
+
// 二进制
|
|
32
|
+
const binary = 0b1010;
|
|
33
|
+
console.log('二进制 0b1010:', binary);
|
|
34
|
+
// 八进制
|
|
35
|
+
const octal = 0o744;
|
|
36
|
+
console.log('八进制 0o744:', octal);
|
|
37
|
+
// 特殊数值
|
|
38
|
+
const infinity = Infinity;
|
|
39
|
+
const notANumber = NaN;
|
|
40
|
+
console.log('Infinity:', infinity);
|
|
41
|
+
console.log('NaN:', notANumber);
|
|
42
|
+
}
|
|
43
|
+
// #endregion
|
|
44
|
+
// #region 示例2: 字符串类型 (string)
|
|
45
|
+
function demonstrateStringType() {
|
|
46
|
+
console.log('\n=== 字符串类型示例 ===');
|
|
47
|
+
// 单引号
|
|
48
|
+
const singleQuote = 'Hello';
|
|
49
|
+
console.log('单引号:', singleQuote);
|
|
50
|
+
// 双引号
|
|
51
|
+
const doubleQuote = "World";
|
|
52
|
+
console.log('双引号:', doubleQuote);
|
|
53
|
+
// 模板字符串
|
|
54
|
+
const name = 'TypeScript';
|
|
55
|
+
const version = 5;
|
|
56
|
+
const template = `${name} 版本 ${version}`;
|
|
57
|
+
console.log('模板字符串:', template);
|
|
58
|
+
// 多行字符串
|
|
59
|
+
const multiline = `
|
|
60
|
+
这是一个
|
|
61
|
+
多行字符串
|
|
62
|
+
示例
|
|
63
|
+
`;
|
|
64
|
+
console.log('多行字符串:', multiline.trim());
|
|
65
|
+
}
|
|
66
|
+
// #endregion
|
|
67
|
+
// #region 示例3: 布尔类型 (boolean)
|
|
68
|
+
function demonstrateBooleanType() {
|
|
69
|
+
console.log('\n=== 布尔类型示例 ===');
|
|
70
|
+
const isTrue = true;
|
|
71
|
+
const isFalse = false;
|
|
72
|
+
console.log('真值:', isTrue);
|
|
73
|
+
console.log('假值:', isFalse);
|
|
74
|
+
// 布尔运算
|
|
75
|
+
const result = isTrue && !isFalse;
|
|
76
|
+
console.log('运算结果:', result);
|
|
77
|
+
// 类型推断
|
|
78
|
+
const inferred = 10 > 5; // TypeScript 自动推断为 boolean
|
|
79
|
+
console.log('推断类型的布尔值:', inferred);
|
|
80
|
+
}
|
|
81
|
+
// #endregion
|
|
82
|
+
// #region 示例4: null 和 undefined
|
|
83
|
+
function demonstrateNullAndUndefined() {
|
|
84
|
+
console.log('\n=== null 和 undefined 示例 ===');
|
|
85
|
+
// undefined - 变量已声明但未赋值
|
|
86
|
+
let notAssigned = undefined;
|
|
87
|
+
console.log('undefined:', notAssigned);
|
|
88
|
+
// null - 表示空值或不存在的对象
|
|
89
|
+
let empty = null;
|
|
90
|
+
console.log('null:', empty);
|
|
91
|
+
// 可选类型(联合类型)
|
|
92
|
+
let maybeString = null;
|
|
93
|
+
console.log('可为 null 的字符串:', maybeString);
|
|
94
|
+
maybeString = 'Hello';
|
|
95
|
+
console.log('赋值后:', maybeString);
|
|
96
|
+
// undefined 和 null 的区别
|
|
97
|
+
console.log('typeof undefined:', typeof undefined);
|
|
98
|
+
console.log('typeof null:', typeof null); // 注意:这是 JavaScript 的历史遗留问题
|
|
99
|
+
}
|
|
100
|
+
// #endregion
|
|
101
|
+
// #region 示例5: Symbol 类型
|
|
102
|
+
function demonstrateSymbolType() {
|
|
103
|
+
console.log('\n=== Symbol 类型示例 ===');
|
|
104
|
+
// 创建唯一的 symbol
|
|
105
|
+
const sym1 = Symbol('key');
|
|
106
|
+
const sym2 = Symbol('key');
|
|
107
|
+
console.log('sym1 === sym2:', sym1 === sym2); // false,每个 symbol 都是唯一的
|
|
108
|
+
// 使用 symbol 作为对象属性
|
|
109
|
+
const obj = {
|
|
110
|
+
[sym1]: 'value1',
|
|
111
|
+
[sym2]: 'value2'
|
|
112
|
+
};
|
|
113
|
+
console.log('obj[sym1]:', obj[sym1]);
|
|
114
|
+
console.log('obj[sym2]:', obj[sym2]);
|
|
115
|
+
// Symbol.for() 创建全局 symbol
|
|
116
|
+
const globalSym1 = Symbol.for('global');
|
|
117
|
+
const globalSym2 = Symbol.for('global');
|
|
118
|
+
console.log('globalSym1 === globalSym2:', globalSym1 === globalSym2); // true
|
|
119
|
+
}
|
|
120
|
+
// #endregion
|
|
121
|
+
// #region 示例6: BigInt 类型
|
|
122
|
+
function demonstrateBigIntType() {
|
|
123
|
+
console.log('\n=== BigInt 类型示例 ===');
|
|
124
|
+
// 创建 BigInt
|
|
125
|
+
const big1 = 9007199254740991n;
|
|
126
|
+
const big2 = BigInt('9007199254740991');
|
|
127
|
+
console.log('BigInt 字面量:', big1);
|
|
128
|
+
console.log('BigInt 构造函数:', big2);
|
|
129
|
+
// BigInt 运算
|
|
130
|
+
const sum = big1 + 1n;
|
|
131
|
+
console.log('BigInt 加法:', sum);
|
|
132
|
+
const product = big1 * 2n;
|
|
133
|
+
console.log('BigInt 乘法:', product);
|
|
134
|
+
// 注意:BigInt 不能与 number 混合运算
|
|
135
|
+
// const invalid = big1 + 1; // 错误!
|
|
136
|
+
const valid = big1 + BigInt(1);
|
|
137
|
+
console.log('正确的混合运算:', valid);
|
|
138
|
+
}
|
|
139
|
+
// #endregion
|
|
140
|
+
if (require.main === module) {
|
|
141
|
+
const examples = [
|
|
142
|
+
demonstrateNumberType,
|
|
143
|
+
demonstrateStringType,
|
|
144
|
+
demonstrateBooleanType,
|
|
145
|
+
demonstrateNullAndUndefined,
|
|
146
|
+
demonstrateSymbolType,
|
|
147
|
+
demonstrateBigIntType
|
|
148
|
+
];
|
|
149
|
+
const exampleNumber = process.argv[2] ? parseInt(process.argv[2]) : 0;
|
|
150
|
+
if (exampleNumber > 0 && exampleNumber <= examples.length) {
|
|
151
|
+
examples[exampleNumber - 1]();
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log('运行所有示例...\n');
|
|
155
|
+
examples.forEach(example => example());
|
|
156
|
+
}
|
|
157
|
+
}
|
package/dist/src/demo/data-types/02-/346/225/260/347/273/204/344/270/216/345/205/203/347/273/204.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript 数组与元组类型
|
|
4
|
+
* ========================
|
|
5
|
+
* 本文件介绍 TypeScript 的数组和元组类型,包括:
|
|
6
|
+
* - 数组的定义和使用
|
|
7
|
+
* - 只读数组
|
|
8
|
+
* - 元组类型
|
|
9
|
+
* - 元组的高级用法
|
|
10
|
+
*
|
|
11
|
+
* 适用版本:TypeScript 5.x
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.demonstrateArrayBasics = demonstrateArrayBasics;
|
|
15
|
+
exports.demonstrateArrayOperations = demonstrateArrayOperations;
|
|
16
|
+
exports.demonstrateReadonlyArray = demonstrateReadonlyArray;
|
|
17
|
+
exports.demonstrateTupleBasics = demonstrateTupleBasics;
|
|
18
|
+
exports.demonstrateTupleAdvanced = demonstrateTupleAdvanced;
|
|
19
|
+
exports.demonstrateReadonlyTuple = demonstrateReadonlyTuple;
|
|
20
|
+
// #region 示例1: 数组的基本定义
|
|
21
|
+
function demonstrateArrayBasics() {
|
|
22
|
+
console.log('\n=== 数组基本定义示例 ===');
|
|
23
|
+
// 方式1:类型 + []
|
|
24
|
+
const numbers = [1, 2, 3, 4, 5];
|
|
25
|
+
console.log('数字数组:', numbers);
|
|
26
|
+
// 方式2:Array<类型>
|
|
27
|
+
const strings = ['a', 'b', 'c'];
|
|
28
|
+
console.log('字符串数组:', strings);
|
|
29
|
+
// 混合类型数组(联合类型)
|
|
30
|
+
const mixed = [1, 'two', 3, 'four'];
|
|
31
|
+
console.log('混合类型数组:', mixed);
|
|
32
|
+
// 多维数组
|
|
33
|
+
const matrix = [
|
|
34
|
+
[1, 2, 3],
|
|
35
|
+
[4, 5, 6],
|
|
36
|
+
[7, 8, 9]
|
|
37
|
+
];
|
|
38
|
+
console.log('二维数组:', matrix);
|
|
39
|
+
}
|
|
40
|
+
// #endregion
|
|
41
|
+
// #region 示例2: 数组的常用操作
|
|
42
|
+
function demonstrateArrayOperations() {
|
|
43
|
+
console.log('\n=== 数组操作示例 ===');
|
|
44
|
+
const fruits = ['apple', 'banana', 'orange'];
|
|
45
|
+
// 添加元素
|
|
46
|
+
fruits.push('grape');
|
|
47
|
+
console.log('push 后:', fruits);
|
|
48
|
+
// 删除最后一个元素
|
|
49
|
+
const last = fruits.pop();
|
|
50
|
+
console.log('pop 返回:', last);
|
|
51
|
+
console.log('pop 后:', fruits);
|
|
52
|
+
// 数组遍历
|
|
53
|
+
console.log('\n遍历数组:');
|
|
54
|
+
fruits.forEach((fruit, index) => {
|
|
55
|
+
console.log(` ${index}: ${fruit}`);
|
|
56
|
+
});
|
|
57
|
+
// map 转换
|
|
58
|
+
const upperFruits = fruits.map(fruit => fruit.toUpperCase());
|
|
59
|
+
console.log('\nmap 转大写:', upperFruits);
|
|
60
|
+
// filter 过滤
|
|
61
|
+
const filtered = fruits.filter(fruit => fruit.length > 5);
|
|
62
|
+
console.log('filter 长度>5:', filtered);
|
|
63
|
+
}
|
|
64
|
+
// #endregion
|
|
65
|
+
// #region 示例3: 只读数组
|
|
66
|
+
function demonstrateReadonlyArray() {
|
|
67
|
+
console.log('\n=== 只读数组示例 ===');
|
|
68
|
+
// 方式1:readonly 修饰符
|
|
69
|
+
const readonlyNumbers = [1, 2, 3];
|
|
70
|
+
console.log('只读数组:', readonlyNumbers);
|
|
71
|
+
// 方式2:ReadonlyArray 类型
|
|
72
|
+
const readonlyStrings = ['a', 'b', 'c'];
|
|
73
|
+
console.log('ReadonlyArray:', readonlyStrings);
|
|
74
|
+
// 只读数组不能修改
|
|
75
|
+
// readonlyNumbers.push(4); // 错误!
|
|
76
|
+
// readonlyNumbers[0] = 10; // 错误!
|
|
77
|
+
// 但可以读取
|
|
78
|
+
console.log('第一个元素:', readonlyNumbers[0]);
|
|
79
|
+
console.log('数组长度:', readonlyNumbers.length);
|
|
80
|
+
// 可以使用不改变原数组的方法
|
|
81
|
+
const mapped = readonlyNumbers.map(n => n * 2);
|
|
82
|
+
console.log('map 结果:', mapped);
|
|
83
|
+
}
|
|
84
|
+
// #endregion
|
|
85
|
+
// #region 示例4: 元组的基本使用
|
|
86
|
+
function demonstrateTupleBasics() {
|
|
87
|
+
console.log('\n=== 元组基本使用示例 ===');
|
|
88
|
+
// 元组:固定长度和类型的数组
|
|
89
|
+
const person = ['Alice', 25];
|
|
90
|
+
console.log('元组:', person);
|
|
91
|
+
console.log('姓名:', person[0]);
|
|
92
|
+
console.log('年龄:', person[1]);
|
|
93
|
+
// 元组解构
|
|
94
|
+
const [name, age] = person;
|
|
95
|
+
console.log(`解构: ${name}, ${age}岁`);
|
|
96
|
+
// 多种类型的元组
|
|
97
|
+
const record = [1, 'active', true];
|
|
98
|
+
console.log('记录元组:', record);
|
|
99
|
+
// 元组数组
|
|
100
|
+
const users = [
|
|
101
|
+
['Bob', 30],
|
|
102
|
+
['Charlie', 35],
|
|
103
|
+
['David', 28]
|
|
104
|
+
];
|
|
105
|
+
console.log('\n用户列表:');
|
|
106
|
+
users.forEach(([name, age]) => {
|
|
107
|
+
console.log(` ${name}: ${age}岁`);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// #endregion
|
|
111
|
+
// #region 示例5: 可选元素和剩余元素
|
|
112
|
+
function demonstrateTupleAdvanced() {
|
|
113
|
+
console.log('\n=== 元组高级特性示例 ===');
|
|
114
|
+
// 可选元素(使用 ?)
|
|
115
|
+
const optionalTuple = ['Alice'];
|
|
116
|
+
console.log('可选元素元组:', optionalTuple);
|
|
117
|
+
const fullTuple = ['Bob', 30];
|
|
118
|
+
console.log('完整元组:', fullTuple);
|
|
119
|
+
// 剩余元素
|
|
120
|
+
const restTuple = ['scores', 90, 85, 92, 88];
|
|
121
|
+
console.log('剩余元素元组:', restTuple);
|
|
122
|
+
const [label, ...scores] = restTuple;
|
|
123
|
+
console.log(`${label}:`, scores);
|
|
124
|
+
const point = [10, 20];
|
|
125
|
+
console.log('\n命名元组 Point:', point);
|
|
126
|
+
const range1 = [0, 10];
|
|
127
|
+
const range2 = [0, 10, 2];
|
|
128
|
+
console.log('Range 示例1:', range1);
|
|
129
|
+
console.log('Range 示例2:', range2);
|
|
130
|
+
}
|
|
131
|
+
// #endregion
|
|
132
|
+
// #region 示例6: 只读元组
|
|
133
|
+
function demonstrateReadonlyTuple() {
|
|
134
|
+
console.log('\n=== 只读元组示例 ===');
|
|
135
|
+
// 只读元组
|
|
136
|
+
const readonlyTuple = ['Alice', 25];
|
|
137
|
+
console.log('只读元组:', readonlyTuple);
|
|
138
|
+
// 不能修改
|
|
139
|
+
// readonlyTuple[0] = 'Bob'; // 错误!
|
|
140
|
+
// readonlyTuple.push('extra'); // 错误!
|
|
141
|
+
// 可以读取
|
|
142
|
+
const [name, age] = readonlyTuple;
|
|
143
|
+
console.log(`读取: ${name}, ${age}岁`);
|
|
144
|
+
// 实际应用:函数返回值
|
|
145
|
+
function getCoordinates() {
|
|
146
|
+
return [100, 200];
|
|
147
|
+
}
|
|
148
|
+
const coords = getCoordinates();
|
|
149
|
+
console.log('坐标:', coords);
|
|
150
|
+
}
|
|
151
|
+
// #endregion
|
|
152
|
+
if (require.main === module) {
|
|
153
|
+
const examples = [
|
|
154
|
+
demonstrateArrayBasics,
|
|
155
|
+
demonstrateArrayOperations,
|
|
156
|
+
demonstrateReadonlyArray,
|
|
157
|
+
demonstrateTupleBasics,
|
|
158
|
+
demonstrateTupleAdvanced,
|
|
159
|
+
demonstrateReadonlyTuple
|
|
160
|
+
];
|
|
161
|
+
const exampleNumber = process.argv[2] ? parseInt(process.argv[2]) : 0;
|
|
162
|
+
if (exampleNumber > 0 && exampleNumber <= examples.length) {
|
|
163
|
+
examples[exampleNumber - 1]();
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.log('运行所有示例...\n');
|
|
167
|
+
examples.forEach(example => example());
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript 对象类型
|
|
4
|
+
* ==================
|
|
5
|
+
* 本文件介绍 TypeScript 的对象类型,包括:
|
|
6
|
+
* - 对象类型的定义
|
|
7
|
+
* - 可选属性和只读属性
|
|
8
|
+
* - 索引签名
|
|
9
|
+
* - 对象类型的扩展
|
|
10
|
+
*
|
|
11
|
+
* 适用版本:TypeScript 5.x
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.demonstrateObjectBasics = demonstrateObjectBasics;
|
|
15
|
+
exports.demonstrateOptionalAndReadonly = demonstrateOptionalAndReadonly;
|
|
16
|
+
exports.demonstrateIndexSignature = demonstrateIndexSignature;
|
|
17
|
+
exports.demonstrateNestedObjects = demonstrateNestedObjects;
|
|
18
|
+
exports.demonstrateIntersectionAndUnion = demonstrateIntersectionAndUnion;
|
|
19
|
+
exports.demonstrateUtilityTypes = demonstrateUtilityTypes;
|
|
20
|
+
// #region 示例1: 对象类型的基本定义
|
|
21
|
+
function demonstrateObjectBasics() {
|
|
22
|
+
console.log('\n=== 对象类型基本定义示例 ===');
|
|
23
|
+
// 内联对象类型
|
|
24
|
+
const user = {
|
|
25
|
+
name: 'Alice',
|
|
26
|
+
age: 25
|
|
27
|
+
};
|
|
28
|
+
console.log('用户对象:', user);
|
|
29
|
+
const person = {
|
|
30
|
+
name: 'Bob',
|
|
31
|
+
age: 30,
|
|
32
|
+
email: 'bob@example.com'
|
|
33
|
+
};
|
|
34
|
+
console.log('Person 对象:', person);
|
|
35
|
+
const product = {
|
|
36
|
+
id: 1,
|
|
37
|
+
name: 'Laptop',
|
|
38
|
+
price: 999.99
|
|
39
|
+
};
|
|
40
|
+
console.log('Product 对象:', product);
|
|
41
|
+
}
|
|
42
|
+
// #endregion
|
|
43
|
+
// #region 示例2: 可选属性和只读属性
|
|
44
|
+
function demonstrateOptionalAndReadonly() {
|
|
45
|
+
console.log('\n=== 可选属性和只读属性示例 ===');
|
|
46
|
+
const user1 = {
|
|
47
|
+
name: 'Alice',
|
|
48
|
+
age: 25
|
|
49
|
+
};
|
|
50
|
+
console.log('没有可选属性:', user1);
|
|
51
|
+
const user2 = {
|
|
52
|
+
name: 'Bob',
|
|
53
|
+
age: 30,
|
|
54
|
+
email: 'bob@example.com'
|
|
55
|
+
};
|
|
56
|
+
console.log('有可选属性:', user2);
|
|
57
|
+
const config = {
|
|
58
|
+
apiUrl: 'https://api.example.com',
|
|
59
|
+
timeout: 5000,
|
|
60
|
+
retries: 3
|
|
61
|
+
};
|
|
62
|
+
console.log('\n配置对象:', config);
|
|
63
|
+
// config.apiUrl = 'new-url'; // 错误!只读属性不能修改
|
|
64
|
+
config.retries = 5; // 可以修改
|
|
65
|
+
console.log('修改 retries 后:', config);
|
|
66
|
+
}
|
|
67
|
+
// #endregion
|
|
68
|
+
// #region 示例3: 索引签名
|
|
69
|
+
function demonstrateIndexSignature() {
|
|
70
|
+
console.log('\n=== 索引签名示例 ===');
|
|
71
|
+
const translations = {
|
|
72
|
+
hello: '你好',
|
|
73
|
+
goodbye: '再见',
|
|
74
|
+
thanks: '谢谢'
|
|
75
|
+
};
|
|
76
|
+
console.log('翻译映射:', translations);
|
|
77
|
+
console.log('hello:', translations['hello']);
|
|
78
|
+
const colors = {
|
|
79
|
+
0: 'red',
|
|
80
|
+
1: 'green',
|
|
81
|
+
2: 'blue'
|
|
82
|
+
};
|
|
83
|
+
console.log('\n颜色数组:', colors);
|
|
84
|
+
const dict = {
|
|
85
|
+
count: 3,
|
|
86
|
+
apple: 5,
|
|
87
|
+
banana: 3,
|
|
88
|
+
orange: 7
|
|
89
|
+
};
|
|
90
|
+
console.log('\n字典对象:', dict);
|
|
91
|
+
}
|
|
92
|
+
// #endregion
|
|
93
|
+
// #region 示例4: 嵌套对象类型
|
|
94
|
+
function demonstrateNestedObjects() {
|
|
95
|
+
console.log('\n=== 嵌套对象类型示例 ===');
|
|
96
|
+
const employee = {
|
|
97
|
+
id: 1,
|
|
98
|
+
name: 'Alice',
|
|
99
|
+
company: {
|
|
100
|
+
name: 'Tech Corp',
|
|
101
|
+
address: {
|
|
102
|
+
street: '123 Main St',
|
|
103
|
+
city: 'San Francisco',
|
|
104
|
+
country: 'USA'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
console.log('员工信息:', JSON.stringify(employee, null, 2));
|
|
109
|
+
console.log('公司名称:', employee.company.name);
|
|
110
|
+
console.log('城市:', employee.company.address.city);
|
|
111
|
+
}
|
|
112
|
+
// #endregion
|
|
113
|
+
// #region 示例5: 对象类型的交叉与联合
|
|
114
|
+
function demonstrateIntersectionAndUnion() {
|
|
115
|
+
console.log('\n=== 对象类型的交叉与联合示例 ===');
|
|
116
|
+
const user = {
|
|
117
|
+
id: 1,
|
|
118
|
+
name: 'Alice',
|
|
119
|
+
email: 'alice@example.com'
|
|
120
|
+
};
|
|
121
|
+
console.log('交叉类型 User:', user);
|
|
122
|
+
function handleResponse(response) {
|
|
123
|
+
if (response.status === 'success') {
|
|
124
|
+
console.log('成功:', response.data);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
console.log('错误:', response.message);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
console.log('\n处理成功响应:');
|
|
131
|
+
handleResponse({ status: 'success', data: 'Hello' });
|
|
132
|
+
console.log('处理错误响应:');
|
|
133
|
+
handleResponse({ status: 'error', message: 'Not found' });
|
|
134
|
+
}
|
|
135
|
+
// #endregion
|
|
136
|
+
// #region 示例6: Record 和 Partial 工具类型
|
|
137
|
+
function demonstrateUtilityTypes() {
|
|
138
|
+
console.log('\n=== 工具类型示例 ===');
|
|
139
|
+
const permissions = {
|
|
140
|
+
admin: ['read', 'write', 'delete'],
|
|
141
|
+
user: ['read', 'write'],
|
|
142
|
+
guest: ['read']
|
|
143
|
+
};
|
|
144
|
+
console.log('权限映射:', permissions);
|
|
145
|
+
const updateUser = {
|
|
146
|
+
name: 'Bob' // 只更新 name
|
|
147
|
+
};
|
|
148
|
+
console.log('\n部分更新:', updateUser);
|
|
149
|
+
const fullUser = {
|
|
150
|
+
id: 1,
|
|
151
|
+
name: 'Charlie' // 两个属性都必须提供
|
|
152
|
+
};
|
|
153
|
+
console.log('必需属性:', fullUser);
|
|
154
|
+
const immutableUser = {
|
|
155
|
+
id: 1,
|
|
156
|
+
name: 'David',
|
|
157
|
+
email: 'david@example.com'
|
|
158
|
+
};
|
|
159
|
+
console.log('只读用户:', immutableUser);
|
|
160
|
+
// immutableUser.name = 'Eve'; // 错误!
|
|
161
|
+
}
|
|
162
|
+
// #endregion
|
|
163
|
+
if (require.main === module) {
|
|
164
|
+
const examples = [
|
|
165
|
+
demonstrateObjectBasics,
|
|
166
|
+
demonstrateOptionalAndReadonly,
|
|
167
|
+
demonstrateIndexSignature,
|
|
168
|
+
demonstrateNestedObjects,
|
|
169
|
+
demonstrateIntersectionAndUnion,
|
|
170
|
+
demonstrateUtilityTypes
|
|
171
|
+
];
|
|
172
|
+
const exampleNumber = process.argv[2] ? parseInt(process.argv[2]) : 0;
|
|
173
|
+
if (exampleNumber > 0 && exampleNumber <= examples.length) {
|
|
174
|
+
examples[exampleNumber - 1]();
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log('运行所有示例...\n');
|
|
178
|
+
examples.forEach(example => example());
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript 函数类型
|
|
4
|
+
* ==================
|
|
5
|
+
* 本文件介绍 TypeScript 的函数类型,包括:
|
|
6
|
+
* - 函数类型的定义
|
|
7
|
+
* - 可选参数和默认参数
|
|
8
|
+
* - 剩余参数
|
|
9
|
+
* - 函数重载
|
|
10
|
+
*
|
|
11
|
+
* 适用版本:TypeScript 5.x
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.demonstrateFunctionBasics = demonstrateFunctionBasics;
|
|
15
|
+
exports.demonstrateFunctionTypes = demonstrateFunctionTypes;
|
|
16
|
+
exports.demonstrateOptionalAndDefaultParams = demonstrateOptionalAndDefaultParams;
|
|
17
|
+
exports.demonstrateRestParameters = demonstrateRestParameters;
|
|
18
|
+
exports.demonstrateFunctionOverloads = demonstrateFunctionOverloads;
|
|
19
|
+
exports.demonstrateReturnTypes = demonstrateReturnTypes;
|
|
20
|
+
// #region 示例1: 函数类型的基本定义
|
|
21
|
+
function demonstrateFunctionBasics() {
|
|
22
|
+
console.log('\n=== 函数类型基本定义示例 ===');
|
|
23
|
+
// 函数声明
|
|
24
|
+
function add(a, b) {
|
|
25
|
+
return a + b;
|
|
26
|
+
}
|
|
27
|
+
console.log('add(2, 3):', add(2, 3));
|
|
28
|
+
// 函数表达式
|
|
29
|
+
const subtract = function (a, b) {
|
|
30
|
+
return a - b;
|
|
31
|
+
};
|
|
32
|
+
console.log('subtract(5, 2):', subtract(5, 2));
|
|
33
|
+
// 箭头函数
|
|
34
|
+
const multiply = (a, b) => {
|
|
35
|
+
return a * b;
|
|
36
|
+
};
|
|
37
|
+
console.log('multiply(3, 4):', multiply(3, 4));
|
|
38
|
+
// 简写箭头函数
|
|
39
|
+
const divide = (a, b) => a / b;
|
|
40
|
+
console.log('divide(10, 2):', divide(10, 2));
|
|
41
|
+
}
|
|
42
|
+
// #endregion
|
|
43
|
+
// #region 示例2: 函数类型表达式
|
|
44
|
+
function demonstrateFunctionTypes() {
|
|
45
|
+
console.log('\n=== 函数类型表达式示例 ===');
|
|
46
|
+
const add = (a, b) => a + b;
|
|
47
|
+
const multiply = (a, b) => a * b;
|
|
48
|
+
console.log('add(2, 3):', add(2, 3));
|
|
49
|
+
console.log('multiply(2, 3):', multiply(2, 3));
|
|
50
|
+
// 使用函数类型作为参数
|
|
51
|
+
function calculate(op, a, b) {
|
|
52
|
+
return op(a, b);
|
|
53
|
+
}
|
|
54
|
+
console.log('calculate(add, 5, 3):', calculate(add, 5, 3));
|
|
55
|
+
console.log('calculate(multiply, 5, 3):', calculate(multiply, 5, 3));
|
|
56
|
+
}
|
|
57
|
+
// #endregion
|
|
58
|
+
// #region 示例3: 可选参数和默认参数
|
|
59
|
+
function demonstrateOptionalAndDefaultParams() {
|
|
60
|
+
console.log('\n=== 可选参数和默认参数示例 ===');
|
|
61
|
+
// 可选参数(使用 ?)
|
|
62
|
+
function greet(name, greeting) {
|
|
63
|
+
return greeting ? `${greeting}, ${name}!` : `Hello, ${name}!`;
|
|
64
|
+
}
|
|
65
|
+
console.log(greet('Alice'));
|
|
66
|
+
console.log(greet('Bob', 'Hi'));
|
|
67
|
+
// 默认参数
|
|
68
|
+
function createUser(name, role = 'user') {
|
|
69
|
+
return { name, role };
|
|
70
|
+
}
|
|
71
|
+
console.log('默认角色:', createUser('Charlie'));
|
|
72
|
+
console.log('指定角色:', createUser('David', 'admin'));
|
|
73
|
+
// 可选参数必须在必需参数之后
|
|
74
|
+
function buildUrl(protocol, domain, port) {
|
|
75
|
+
return port ? `${protocol}://${domain}:${port}` : `${protocol}://${domain}`;
|
|
76
|
+
}
|
|
77
|
+
console.log(buildUrl('https', 'example.com'));
|
|
78
|
+
console.log(buildUrl('http', 'localhost', 3000));
|
|
79
|
+
}
|
|
80
|
+
// #endregion
|
|
81
|
+
// #region 示例4: 剩余参数
|
|
82
|
+
function demonstrateRestParameters() {
|
|
83
|
+
console.log('\n=== 剩余参数示例 ===');
|
|
84
|
+
// 剩余参数(使用 ...)
|
|
85
|
+
function sum(...numbers) {
|
|
86
|
+
return numbers.reduce((total, n) => total + n, 0);
|
|
87
|
+
}
|
|
88
|
+
console.log('sum(1, 2, 3):', sum(1, 2, 3));
|
|
89
|
+
console.log('sum(1, 2, 3, 4, 5):', sum(1, 2, 3, 4, 5));
|
|
90
|
+
// 混合使用普通参数和剩余参数
|
|
91
|
+
function introduce(greeting, ...names) {
|
|
92
|
+
return `${greeting} ${names.join(', ')}!`;
|
|
93
|
+
}
|
|
94
|
+
console.log(introduce('Hello', 'Alice', 'Bob', 'Charlie'));
|
|
95
|
+
// 剩余参数必须是最后一个参数
|
|
96
|
+
function logWithPrefix(prefix, ...messages) {
|
|
97
|
+
messages.forEach(msg => console.log(`[${prefix}] ${msg}`));
|
|
98
|
+
}
|
|
99
|
+
console.log('\n日志示例:');
|
|
100
|
+
logWithPrefix('INFO', 'Server started', 'Port 3000', 'Ready');
|
|
101
|
+
}
|
|
102
|
+
// #endregion
|
|
103
|
+
// #region 示例5: 函数重载
|
|
104
|
+
function demonstrateFunctionOverloads() {
|
|
105
|
+
console.log('\n=== 函数重载示例 ===');
|
|
106
|
+
// 实现签名
|
|
107
|
+
function format(value) {
|
|
108
|
+
if (typeof value === 'string') {
|
|
109
|
+
return `"${value}"`;
|
|
110
|
+
}
|
|
111
|
+
else if (typeof value === 'number') {
|
|
112
|
+
return value.toFixed(2);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return value ? 'Yes' : 'No';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
console.log('format("hello"):', format('hello'));
|
|
119
|
+
console.log('format(3.14159):', format(3.14159));
|
|
120
|
+
console.log('format(true):', format(true));
|
|
121
|
+
function makeDate(yearOrTimestamp, month, day) {
|
|
122
|
+
if (month !== undefined && day !== undefined) {
|
|
123
|
+
return new Date(yearOrTimestamp, month - 1, day);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return new Date(yearOrTimestamp);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
console.log('\nmakeDate(1609459200000):', makeDate(1609459200000));
|
|
130
|
+
console.log('makeDate(2024, 1, 1):', makeDate(2024, 1, 1));
|
|
131
|
+
}
|
|
132
|
+
// #endregion
|
|
133
|
+
// #region 示例6: void、never 和返回类型
|
|
134
|
+
function demonstrateReturnTypes() {
|
|
135
|
+
console.log('\n=== 返回类型示例 ===');
|
|
136
|
+
// void - 没有返回值
|
|
137
|
+
function logMessage(message) {
|
|
138
|
+
console.log('Log:', message);
|
|
139
|
+
}
|
|
140
|
+
logMessage('This is a void function');
|
|
141
|
+
// never - 永远不会返回(抛出异常或无限循环)
|
|
142
|
+
function throwError(message) {
|
|
143
|
+
throw new Error(message);
|
|
144
|
+
}
|
|
145
|
+
function infiniteLoop() {
|
|
146
|
+
while (true) {
|
|
147
|
+
// 无限循环
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
console.log('\nnever 类型用于永不返回的函数');
|
|
151
|
+
// 类型推断
|
|
152
|
+
function inferredReturn(x) {
|
|
153
|
+
return x * 2; // TypeScript 推断返回类型为 number
|
|
154
|
+
}
|
|
155
|
+
console.log('inferredReturn(5):', inferredReturn(5));
|
|
156
|
+
// 联合类型返回值
|
|
157
|
+
function parseValue(input) {
|
|
158
|
+
const parsed = parseInt(input);
|
|
159
|
+
return isNaN(parsed) ? null : parsed;
|
|
160
|
+
}
|
|
161
|
+
console.log('parseValue("123"):', parseValue('123'));
|
|
162
|
+
console.log('parseValue("abc"):', parseValue('abc'));
|
|
163
|
+
}
|
|
164
|
+
// #endregion
|
|
165
|
+
if (require.main === module) {
|
|
166
|
+
const examples = [
|
|
167
|
+
demonstrateFunctionBasics,
|
|
168
|
+
demonstrateFunctionTypes,
|
|
169
|
+
demonstrateOptionalAndDefaultParams,
|
|
170
|
+
demonstrateRestParameters,
|
|
171
|
+
demonstrateFunctionOverloads,
|
|
172
|
+
demonstrateReturnTypes
|
|
173
|
+
];
|
|
174
|
+
const exampleNumber = process.argv[2] ? parseInt(process.argv[2]) : 0;
|
|
175
|
+
if (exampleNumber > 0 && exampleNumber <= examples.length) {
|
|
176
|
+
examples[exampleNumber - 1]();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
console.log('运行所有示例...\n');
|
|
180
|
+
examples.forEach(example => example());
|
|
181
|
+
}
|
|
182
|
+
}
|