【问题标题】:How to get optional chaining working in TypeScript?如何在 TypeScript 中使用可选链接?
【发布时间】:2020-03-02 16:12:14
【问题描述】:

看起来像可选链接has landedHere's an example

我想不通的是如何让 TS 正确编译它。我的项目中没有出现任何语法错误,但是:

let imageFileId = (await db.query(sql`select id from image_files where sha256=${sha256}`))[0]?.id;

输出为:

let imageFileId = (await db.query(mysql3_1.sql `select id from image_files where sha256=${sha256}`))[0]?.id;

在我们获得 Node 的原生支持之前,它不会运行。

这是我的 tsconfig:

{
    "compilerOptions": {
        "strict": true,
        "importHelpers": false,
        "inlineSources": true,
        "noEmitOnError": true,
        "pretty": true,
        "module": "commonjs",
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": false,
        "removeComments": false,
        "preserveConstEnums": false,
        "sourceMap": true,
        "lib": ["es2018"],
        "skipLibCheck": false,
        "outDir": "dist",
        "target": "esnext",
        "declaration": false,
        "resolveJsonModule": true,
        "esModuleInterop": false,
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "baseUrl": ".",
        "paths": {
            "*": ["src/*"]
        },
        "noEmit": false
    },
    "files": [
        "src/index"
    ],
    "include": [
        "src/**/*.d.ts"
    ]
}

我需要启用其他选项来编译?. 运算符吗?

请注意我使用 Babel,我不想把它带入图片。

【问题讨论】:

    标签: typescript optional-chaining


    【解决方案1】:

    问题是您的目标是esnext,这将告诉编译器按原样输出所有语言功能,而无需进行任何转译。将语言设置为 es2020(或更低),?.?? 将被转译为兼容代码:

    (async function () {
        let imageFileId = (await db.query(sql`select id from image_files where sha256=${sha256}`))[0]?.id;
    })()
    

    Playground Link

    不幸的是,对于哪些语言特性被编译以及哪些语言特性不需要选择一个整体,没有细粒度的控制,

    【讨论】:

    • 问题是我也在使用节点支持一段时间的 BigInt :-( "TS2737: BigInt literals are not available when target below ESNext"
    • @mpen 我只是在编辑我的答案来解决这个问题。不幸的是,没有办法控制哪些特定的语言特性被编译,哪些不被编译
    • 升级到 TypeScript 3.8 后我又遇到了同样的问题。我认为您实际上应该以 es2019 为目标,以便“填充”可选链接。
    • @icl7126 是对的。对于 TS 3.8.3,您必须将 ES2019 设置为目标
    • 设置 target: ES2019 对于 TS 3.9.5 仍然适用
    【解决方案2】:

    好吧,我不想使用 Babel,因为那样我就必须弄清楚如何替换 ts-node。那里有一堆过时的文档提到旧的 Babel 包,但这些说明应该在 2019 年 11 月起生效:

    添加.babelrc 文件:

    {
        "presets": [
            ["@babel/preset-env",{"targets": {"node": "current"}}],
            "@babel/preset-typescript"
        ],
        "plugins": [
            "@babel/plugin-syntax-bigint"
        ]
    }
    

    添加这些部门:

      "devDependencies": {
        "@babel/cli": "^7.7.0",
        "@babel/core": "^7.7.0",
        "@babel/node": "^7.7.0",
        "@babel/plugin-syntax-bigint": "^7.4.4",
        "@babel/preset-env": "^7.7.1",
        "@babel/preset-typescript": "^7.7.0",
        "@types/node": "^12.7.5",
        "typescript": "^3.7.2"
      }
    

    执行您的代码:

    node_modules/.bin/babel-node --extensions ".ts" src/index.ts
    

    --extensions ".ts" 非常重要,即使您明确尝试执行一个 .ts 文件,它也不会在没有它的情况下对其进行转换。

    我喜欢使用 GNU Make 而不是 package.json 脚本:

    MAKEFLAGS += --no-builtin-rules
    .SUFFIXES:
    NM := node_modules/.bin
    .PHONY: build start dev clean test publish
    
    ## commands
    ########################################
    
    __default:
        $(error Please specify a target)
    
    build: build-types build-js dist/package.json
    
    build-types: node_modules/.yarn-integrity
        $(NM)/tsc --emitDeclarationOnly
    
    build-js: node_modules/.yarn-integrity
        $(NM)/babel src --out-dir dist --extensions ".ts" --source-maps inline
    
    run: node_modules/.yarn-integrity
        $(NM)/babel-node --extensions ".ts" src/index.ts
    
    check: node_modules/.yarn-integrity
        $(NM)/tsc --noEmit
    
    dist:
        mkdir -p $@
    
    clean:
        rm -rf node_modules dist yarn-error.log
    
    dist/package.json: package.json | dist
        jq 'del(.private, .devDependencies, .scripts, .eslintConfig, .babel)' $< > $@
    
    ## files
    ########################################
    
    node_modules/.yarn-integrity: yarn.lock
        @yarn install --frozen-lockfile --production=false --check-files
        @touch -mr $@ $<
    
    yarn.lock: package.json
        @yarn check --integrity
        @touch -mr $@ $<
    

    或者只是从Microsoft's TypeScript Babel Starter复制。

    【讨论】:

      猜你喜欢
      • 2019-08-27
      • 2020-03-24
      • 2020-01-24
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 2016-11-27
      • 2022-11-10
      • 1970-01-01
      相关资源
      最近更新 更多