Revision e71614a185eaafa080664902f1bb7fa2802dbd01 authored by Eli Barzilay on 13 February 2020, 21:09:20 UTC, committed by Eli Barzilay on 27 February 2020, 21:43:29 UTC
Fixes #32465.

After this was done, I continued to extend the implementation to handle
TupleLike types but it'ss broken since JS doesn't allow splicing
TupleLike values into array literals so pulled that out, and instead
keeping it for reference below.  (It Includes tests, which are broken
too.)

modified   src/compiler/checker.ts
@@ -22268,6 +22268,21 @@ namespace ts {
                         else hasNonEndingSpreadElement = true;
                     }
                 }
+                else if (spreadType && isTupleLikeType(spreadType)) {
+                    let i = 0, tupleEltType: Type | undefined;
+                    while (tupleEltType = getTypeOfPropertyOfType(spreadType, "" + i as __String)) {
+                        elementTypes.push(tupleEltType);
+                        i++;
+                    }
+                    const stringIndexInfo = getIndexInfoOfType(spreadType, IndexKind.String);
+                    const numberIndexInfo = getIndexInfoOfType(spreadType, IndexKind.Number);
+                    if (stringIndexInfo || numberIndexInfo) {
+                        if (stringIndexInfo) elementTypes.push(stringIndexInfo.type);
+                        if (numberIndexInfo) elementTypes.push(numberIndexInfo.type);
+                        if (i === elementCount - 1) hasEndingSpreadElement = true;
+                        else hasNonEndingSpreadElement = true;
+                    }
+                }
                 else {
                     if (inDestructuringPattern && spreadType) {
                         // Given the following situation:
new file   tests/cases/compiler/spliceTupleLikesWIntegers.ts
@@ -0,0 +1,23 @@
+declare const sb: { [0]: string, [1]: boolean };
+
+let k1: [number, string, boolean];
+k1 = [1, ...sb];
+
+let k2: [number, string, boolean, number];
+k2 = [1, ...sb, 1];
+
+// declare const sb_: [string, ...boolean[]];
+
+// let k3: [number, string, ...boolean[]];
+// k3 = [1, ...sb_];
+
+// declare const sbb_: [string, boolean, ...boolean[]];
+
+// let k4: [number, string, ...boolean[]];
+// k4 = [1, ...sbb_];
+
+// let k5: [number, string, boolean, ...boolean[]];
+// k5 = [1, ...sbb_];
+
+// let k6: [number, string, boolean, boolean, ...boolean[]];
+// k6 = [1, ...sbb_];
new file   tests/cases/compiler/spliceTupleLikesWStrings.ts
@@ -0,0 +1,23 @@
+declare const sb: { 0: string, 1: boolean };
+
+let k1: [number, string, boolean];
+k1 = [1, ...sb];
+
+let k2: [number, string, boolean, number];
+k2 = [1, ...sb, 1];
+
+declare const sb_: { 0: string, [s: string]: (boolean|string) };
+
+let k3: [number, string, ...(boolean|string)[]];
+k3 = [1, ...sb_];
+
+declare const sbb_: { 0: string, 1: boolean, [s: string]: (boolean|string) };
+
+let k4: [number, string, boolean, ...(boolean|string)[]];
+k4 = [1, ...sbb_];
+
+// let k5: [number, string, boolean, ...(boolean|string)[]];
+// k5 = [1, ...sbb_];
+
+// let k6: [number, string, boolean, boolean, ...(boolean|string)[]];
+// k6 = [1, ...sbb_];
1 parent 6c5c48c
Raw File
package.json
{
    "name": "typescript",
    "author": "Microsoft Corp.",
    "homepage": "https://www.typescriptlang.org/",
    "version": "3.9.0",
    "license": "Apache-2.0",
    "description": "TypeScript is a language for application scale JavaScript development",
    "keywords": [
        "TypeScript",
        "Microsoft",
        "compiler",
        "language",
        "javascript"
    ],
    "bugs": {
        "url": "https://github.com/Microsoft/TypeScript/issues"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/Microsoft/TypeScript.git"
    },
    "main": "./lib/typescript.js",
    "typings": "./lib/typescript.d.ts",
    "bin": {
        "tsc": "./bin/tsc",
        "tsserver": "./bin/tsserver"
    },
    "engines": {
        "node": ">=4.2.0"
    },
    "devDependencies": {
        "@octokit/rest": "latest",
        "@types/browserify": "latest",
        "@types/chai": "latest",
        "@types/convert-source-map": "latest",
        "@types/glob": "latest",
        "@types/gulp": "^4.0.5",
        "@types/gulp-concat": "latest",
        "@types/gulp-newer": "latest",
        "@types/gulp-rename": "0.0.33",
        "@types/gulp-sourcemaps": "0.0.32",
        "@types/jake": "latest",
        "@types/merge2": "latest",
        "@types/microsoft__typescript-etw": "latest",
        "@types/minimatch": "latest",
        "@types/minimist": "latest",
        "@types/mkdirp": "latest",
        "@types/mocha": "latest",
        "@types/ms": "latest",
        "@types/node": "latest",
        "@types/node-fetch": "^2.3.4",
        "@types/q": "latest",
        "@types/source-map-support": "latest",
        "@types/through2": "latest",
        "@types/travis-fold": "latest",
        "@types/xml2js": "^0.4.0",
        "@typescript-eslint/eslint-plugin": "2.18.0",
        "@typescript-eslint/experimental-utils": "2.18.0",
        "@typescript-eslint/parser": "2.18.0",
        "async": "latest",
        "azure-devops-node-api": "^8.0.0",
        "browser-resolve": "^1.11.2",
        "browserify": "latest",
        "chai": "latest",
        "chalk": "latest",
        "convert-source-map": "latest",
        "del": "5.1.0",
        "eslint": "6.8.0",
        "eslint-formatter-autolinkable-stylish": "1.1.1",
        "eslint-plugin-import": "2.20.0",
        "eslint-plugin-jsdoc": "21.0.0",
        "eslint-plugin-no-null": "1.0.2",
        "fancy-log": "latest",
        "fs-extra": "^6.0.1",
        "glob": "latest",
        "gulp": "^4.0.0",
        "gulp-concat": "latest",
        "gulp-insert": "latest",
        "gulp-newer": "latest",
        "gulp-rename": "latest",
        "gulp-sourcemaps": "latest",
        "istanbul": "latest",
        "merge2": "latest",
        "minimist": "latest",
        "mkdirp": "latest",
        "mocha": "latest",
        "mocha-fivemat-progress-reporter": "latest",
        "ms": "latest",
        "node-fetch": "^2.6.0",
        "playwright": "latest",
        "plugin-error": "latest",
        "pretty-hrtime": "^1.0.3",
        "prex": "^0.4.3",
        "q": "latest",
        "remove-internal": "^2.9.2",
        "source-map-support": "latest",
        "through2": "latest",
        "travis-fold": "latest",
        "typescript": "next",
        "vinyl": "latest",
        "vinyl-sourcemaps-apply": "latest",
        "xml2js": "^0.4.19"
    },
    "scripts": {
        "prepare": "gulp build-eslint-rules",
        "pretest": "gulp tests",
        "test": "gulp runtests-parallel --light=false",
        "test:eslint-rules": "gulp run-eslint-rules-tests",
        "build": "npm run build:compiler && npm run build:tests",
        "build:compiler": "gulp local",
        "build:tests": "gulp tests",
        "start": "node lib/tsc",
        "clean": "gulp clean",
        "gulp": "gulp",
        "jake": "gulp",
        "lint": "gulp lint",
        "lint:ci": "gulp lint --ci",
        "lint:compiler": "gulp lint-compiler",
        "lint:scripts": "gulp lint-scripts",
        "setup-hooks": "node scripts/link-hooks.js"
    },
    "browser": {
        "fs": false,
        "os": false,
        "path": false,
        "crypto": false,
        "buffer": false,
        "@microsoft/typescript-etw": false,
        "source-map-support": false,
        "inspector": false
    },
    "dependencies": {}
}
back to top