美文网首页
用ts开发命令行程序

用ts开发命令行程序

作者: sweetBoy_9126 | 来源:发表于2019-08-18 15:10 被阅读0次
    最简单的命令行程序
    • 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是可选参数,可以传也可以不传

    相关文章

      网友评论

          本文标题:用ts开发命令行程序

          本文链接:https://www.haomeiwen.com/subject/hlursctx.html