最简单的命令行程序
- 1.ts
#!/usr/bin/env ts-node
console.log('hello world')
然后给该文件添加执行权限:`chmod +x ./1.ts (Windows 用户不需要做这个,直接在 Git Bash 输入 ./1.ts 即可运行)
执行 ./1.ts
就会看到 hello world
接受命令行参数
#!/usr/bin/env ts-node
console.log(process.argv)
process.argv可以打印出你命令行输入的命令和参数,比如你输入
./1.ts xxx
会得到下面的
[ 'node',
'/Users/mac/Desktop/study/typeScript/tsdemo/1.ts',
'xxx' ]
第一个值是你的环境,第二个是你当前文件的路径,第三个包括之后的都是你输入的参数
但是实际上我们直接运行./1.ts xxx会报错
/usr/local/lib/node_modules/ts-node/src/index.ts:261
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
1.ts(2,13): error TS2304: Cannot find name 'process'.
at createTSError (/usr/local/lib/node_modules/ts-node/src/index.ts:261:12)
at getOutput (/usr/local/lib/node_modules/ts-node/src/index.ts:367:40)
at Object.compile (/usr/local/lib/node_modules/ts-node/src/index.ts:557:11)
at Module.m._compile (/usr/local/lib/node_modules/ts-node/src/index.ts:439:43)
at Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Object.require.extensions.(anonymous function) [as .ts] (/usr/local/lib/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
报错说得很清楚,2.ts(2,13): error TS2304: Cannot find name 'process'.
找不到 process。
实际上这是 Node.js 的全局变量,不可能找不到。
这就是 TS 的厉害之处:如果你不告诉我 process 是什么,我就不允许你用 process。
那么如何告诉 TS process 是什么呢?
方法如下:
初始化项目的 package.json
npm init -y
安装 node 相关的类型定义
npm install @types/node
再次运行 ./1.ts xxx
./1.ts xxx
[ 'node', '/Users/frank/TypeScript/tsdemo/2.ts', 'xxx' ]
就可以了。
使用ts做加法
add.ts(记得添加可执行权限,Windows 用户不需要加)
#!/usr/bin/env ts-node
const a = process.argv[2];
const b = process.argv[3];
console.log(a + b);
# ./add.ts 1 2
12
1 + 2 居然等于 12,这计算器想个傻子一样。
这是因为目前 a b 的类型是 Any,然后参数 1 2 其实是字符串,所以 a b 也是字符串 1 2 。
为了将 a b 变成数字,我们需要改代码:
#!/usr/bin/env ts-node
const a: number = parseInt(process.argv[2]);
const b: number = parseInt(process.argv[3]);
console.log(a + b);
# ./add.ts 1 2
3
1 + 2 = 3 成功!
但是如果我们某一个参数我们传进去的不是数字,那么parseInt会将它转成NaN,这也不是我们想要的,比如下面
# ./add.ts 1 s
NaN
改代码
#!/usr/bin/env ts-node
const a: number = parseInt(process.argv[2]);
const b: number = parseInt(process.argv[3]);
if (Number.isNaN(a) || Number.isNaN(b)) {
console.log('输入不合法');
}
console.log(a + b);
报错如下:
/usr/local/lib/node_modules/ts-node/src/index.ts:261
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
add.ts(5,12): error TS2339: Property 'isNaN' does not exist on type 'NumberConstructor'.
add.ts(5,31): error TS2339: Property 'isNaN' does not exist on type 'NumberConstructor'.
at createTSError (/usr/local/lib/node_modules/ts-node/src/index.ts:261:12)
at getOutput (/usr/local/lib/node_modules/ts-node/src/index.ts:367:40)
at Object.compile (/usr/local/lib/node_modules/ts-node/src/index.ts:557:11)
at Module.m._compile (/usr/local/lib/node_modules/ts-node/src/index.ts:439:43)
at Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Object.require.extensions.(anonymous function) [as .ts] (/usr/local/lib/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
原因:ts本身不支持es6的语法,解决办法:添加一个tsconfig.json文件
- tsconfig.json
{
"compilerOptions": {
"lib": ["es2015"]
}
}
再次运行
# ./add.ts 1 s
输入不合法
NaN
问题:我们如果不满足条件的情况下只希望打印出‘输入不合法’,而不希望继续执行a+b,可我们不能直接在if语句里写return
解决办法:如果我们需要退出程序,只能使用 process.exit(N)
,其中的 N 是返回值。
成功的情况下返回值里写0,失败里面写非0的数字
#!/usr/bin/env ts-node
const a: number = parseInt(process.argv[2]);
const b: number = parseInt(process.argv[3]);
if (Number.isNaN(a) || Number.isNaN(b)) {
console.log('输入不合法');
process.exit(2);
}
console.log(a + b);
process.exit(0);
# ./add.ts 1 s
输入不合法
族谱
class Person {
// 默认是一个空数组
children: Person[] = [];
constructor(public name) {}
// 没有返回值就写:void
appenChild(child: Person): void {
this.children.push(child);
}
introduceFamily(): void {
console.log(this.name)
this.children.forEach(child => {
child.introduceFamily();
});
}
}
let grandPa = new Person('王麻子')
let child1 = new Person('王子')
let child2 = new Person('王大锤')
let person11 = new Person('王毛')
let person12 = new Person('王水')
let person21 = new Person('王毛2')
let person22 = new Person('王水2')
grandPa.appenChild(child1)
grandPa.appenChild(child2)
child1.appenChild(person11)
child1.appenChild(person12)
grandPa.introduceFamily()
# ./x.ts
王麻子
王子
王毛
王水
王大锤
王毛2
王水2
注意:*TS 可以自定义类型,所有class和interface都是类型,所以我们上面可以指定类型为Person
上面的代码层级结构看上去不会很明显,为了更好的体现出来,我们给层级下面加---,每深入一级就多加三根杠
class Person {
children: Person[] = [];
constructor(public name) { }
appenChild(child: Person): void {
this.children.push(child);
}
introduceFamily(n?: number): void {
let n1 = n || 1
let profix = ('---').repeat(n1 - 1)
console.log(profix + this.name)
this.children.forEach(child => {
child.introduceFamily(n1 + 1);
});
}
}
grandPa.appenChild(child1)
grandPa.appenChild(child2)
child1.appenChild(person11)
child1.appenChild(person12)
child2.appenChild(person21)
child2.appenChild(person22)
grandPa.introduceFamily()
# ./x.ts
王麻子
---王子
------王毛
------王水
---王大锤
------王毛2
------王水2
上面的n? : number 意思是n是可选参数,可以传也可以不传
网友评论