profile
viewpoint

andrewbranch/gatsby-remark-vscode 199

Gatsby plugin to provide VS Code’s syntax highlighting to Markdown code fences

andrewbranch/merge-props 30

Merges className, style, and event handler props for React elements

andrewbranch/react-use-hover 24

State hook to determine whether a React element is being hovered

andrewbranch/definitely-not-slow 2

This repo has moved:

andrewbranch/es6-set-proptypes 2

React PropTypes for ES6 Sets and compatible interfaces

andrewbranch/GlanceCalendar 2

macOS menu bar clock replacement with calendar view. Supports dark mode. 🌒

andrewbranch/notes-app 2

Prototype of note-taking Electron app

andrewbranch/draft-js-transactions 1

Stage multiple codependent edits to a Draft EditorState and apply them all at once

andrewbranch/no-undefined-style-loader 1

Webpack loader that warns when an undefined key is referenced on a required CSS file

IssuesEvent

issue commentmicrosoft/TypeScript

Using && with spread operator causes "overridden" error if one of the types is "any"

Sure: https://www.typescriptlang.org/play/#code/DYUwLgBAlgzgKgJxCAEiAhgExAgXBdAOwE8IBeCQgV2GAEIBuAKADMrCBjMKAe0IhY8eACgCUEAN5MIMiEjBUE-KbNURMsAA7B0xfACIARsB4cA1voA00tTIB0D4XTqxEyNFhwQAZN8k3bVQ0YbV0DFlAADysAtQBfUVi4pmTBEVEgA

I assume you didn’t mean to close this 😄

mastrzyz

comment created time in 10 hours

delete branch andrewbranch/TypeScript

delete branch : bug/37901

delete time in 14 hours

push eventmicrosoft/TypeScript

Andrew Branch

commit sha 2d6d5db33af891d87d5cb933f8d67b402282223c

Fix getTypeAtLocation for dotted implements clauses (#39363) * Fix getTypeAtLocation for dotted implements clauses * Fix typo

view details

push time in 14 hours

PR merged microsoft/TypeScript

Fix getTypeAtLocation for dotted implements clauses Author: Team

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #37901

+30 -1

0 comment

2 changed files

andrewbranch

pr closed time in 14 hours

issue closedmicrosoft/TypeScript

`getTypeAtLocation` fails on a `PropertyAccessExpression` in a type position

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

<!-- Please try to reproduce the issue with the latest published version. It may have already been fixed. For npm: typescript@next This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly --> TypeScript Version: 3.8.3

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms: getTypeAtLocation

Code

declare class SomeClass implements NodeJS.CallSite {
  //
}

Expected behavior: getTypeAtLocation on the PropertyAccessExpression node for NodeJS.CallSite should return CallSite.

Actual behavior: Instead, it returns any with intrinsic name error.

Notes Note that getTypeAtLocation on the parent ExpressionWithTypeArguments does actually succeed.

Playground Link: N/A

Related Issues: #35233

Thanks to @bradzacher for finding this!

closed time in 14 hours

uniqueiniquity

push eventandrewbranch/TypeScript

Andrew Branch

commit sha 6350e0f526e8c2646e962c30bc9abf0b6b594fd8

Fix typo

view details

push time in 16 hours

pull request commentmicrosoft/TypeScript

Fix test semantic merge conflict between #39348 and #39130

That bothered me when I wrote that test 😄

weswigham

comment created time in 16 hours

Pull request review commentmicrosoft/TypeScript

Fix getTypeAtLocation for dotted implements clauses

 describe("unittests:: Public APIs:: isPropertyName", () => {         assert.isTrue(ts.isPropertyName(prop), "PrivateIdentifier must be a valid property name.");
     });
 });
+
+describe("unittests:: Public APIs:: getTypeAtLocation", () => {
+    it("works on PropertyAccessExpression in implements clause", () => {

Mmmmmaaybe? I didn’t think about quick info. I had hoped that the type baseliner would do the job, but it didn’t drill all the way down to the problematic node. Quick info also seems susceptible to future changes in which nodes it calls getTypeAtLocation on, even if it works now. I do wish it was easier to set up this kind of test.

andrewbranch

comment created time in 17 hours

issue commentmicrosoft/TypeScript

auto-complete not work but type check still working

I’m not sure what’s going on here off the top of my head, but it seems a bit suspicious that quick info is showing P instantiated to any[] when the type error clearly indicates that P has been correctly instantiated to the tuple [typeof func, typeof func2].

image

This is definitely reminiscent of some very difficult problems we’ve had in the past with object literal completions at inference-affecting positions (and this could be a side effect of the fix), but I would hope this is fixable.

xuzhanhh

comment created time in 17 hours

pull request commentmicrosoft/TypeScript

Type `this` in more constructor functions

Also, the this type is used everywhere except constructor function bodies, so it's not like we're exposing a new code path to the world.

Ah, I didn’t realize that. That makes it seem like a smaller change then.

sandersn

comment created time in 17 hours

issue commentmicrosoft/TypeScript

Type-only auto import fails with an existing value import

This is expected behavior. A type-only import is unnecessary if there is already a regular import from the same module. The point of type-only imports is to eliminate runtime dependencies between modules. You already have an unavoidable runtime dependency on that module, so adding a type-only import is meaningless. Auto-imports will only give you a type-only import if a regular import would cause an error under --importsNotUsedAsValues=error. The error, if you had one, would be telling you that you’re creating a runtime dependency you don’t need. Since you do need the runtime dependency, there’s no error (https://github.com/microsoft/TypeScript/issues/36959), so auto-imports proceeds with its normal behavior.

kingdaro

comment created time in 17 hours

Pull request review commentmicrosoft/TypeScript

Insert auto-imports in sorted order

 namespace ts {         return node.modifiers && find(node.modifiers, m => m.kind === kind);
     }
 
-    export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: Statement | readonly Statement[], blankLineBetween: boolean): void {
+    export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[], blankLineBetween: boolean): void {
         const decl = isArray(imports) ? imports[0] : imports;
-        const importKindPredicate = decl.kind === SyntaxKind.VariableStatement ? isRequireVariableDeclarationStatement : isAnyImportSyntax;
-        const lastImportDeclaration = findLast(sourceFile.statements, statement => importKindPredicate(statement));
-        if (lastImportDeclaration) {
-            if (isArray(imports)) {
-                changes.insertNodesAfter(sourceFile, lastImportDeclaration, imports);
-            }
-            else {
-                changes.insertNodeAfter(sourceFile, lastImportDeclaration, imports);
+        const importKindPredicate: (node: Node) => node is AnyImportOrRequireStatement = decl.kind === SyntaxKind.VariableStatement ? isRequireVariableStatement : isAnyImportSyntax;
+        const existingImportStatements = filter(sourceFile.statements, importKindPredicate);
+        const sortedNewImports = isArray(imports) ? stableSort(imports, OrganizeImports.compareImportsOrRequireStatements) : [imports];
+        if (!existingImportStatements.length) {
+            changes.insertNodesAtTopOfFile(sourceFile, sortedNewImports, blankLineBetween);
+        }
+        else if (existingImportStatements && OrganizeImports.importsAreSorted(existingImportStatements)) {
+            for (const newImport of sortedNewImports) {
+                const insertionIndex = OrganizeImports.getImportDeclarationInsertionIndex(existingImportStatements, newImport);

Yeah, the binary search wasn’t intended to squeeze performance; it was just the first thing that came to mind noting that the existing imports would always be sorted. And when I wrote getImportDeclarationInsertionIndex, I was thinking about inserting a single import (which is the typical case—adding one import via a completion). So when I came around to this section, I was just using the APIs I had already written. There is definitely a way to do this with fewer iterations now that you mention it, but I’m not too concerned; I think the size of both lists will usually be small. I’m open to revisiting it if you feel strongly about it, though.

andrewbranch

comment created time in 17 hours

Pull request review commentmicrosoft/TypeScript

Insert auto-imports in sorted order

 namespace ts {         return node.modifiers && find(node.modifiers, m => m.kind === kind);
     }
 
-    export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: Statement | readonly Statement[], blankLineBetween: boolean): void {
+    export function insertImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, imports: AnyImportOrRequireStatement | readonly AnyImportOrRequireStatement[], blankLineBetween: boolean): void {

That’s correct.

andrewbranch

comment created time in 17 hours

push eventmicrosoft/TypeScript

Andrew Branch

commit sha 0c75021860735da26a2f53cad79d27f27b005ca5

Process type nodes in codefixes/refactors for auto-imports recursively (#39130) * Process type nodes for auto-imports recursively * Rename function

view details

push time in 18 hours

delete branch andrewbranch/TypeScript

delete branch : bug/34995

delete time in 18 hours

PR merged microsoft/TypeScript

Reviewers
Process type nodes in codefixes/refactors for auto-imports recursively Author: Team

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #34995

The first time I fixed this bug, it didn’t account for ImportTypeNodes nested inside other types. Now it uses a recursive visitor.

+43 -52

1 comment

3 changed files

andrewbranch

pr closed time in 18 hours

issue closedmicrosoft/TypeScript

Implementing interface puts relative imports

TypeScript Version: 3.7.2

Code

  • git clone https://github.com/microsoft/vscode.git
  • yarn
  • open VSCode on anythingQuickAccess.ts
  • type in the top:
class FooHandler implements IEditorGroup {

}
  • fix the error by letting it implement the interface

Expected behavior: Code that gets generated does not use inline imports.

Actual behavior: Code that gets generated adds inline imports:

class FooHandler implements IEditorGroup {
	onDidGroupChange: Event<IGroupChangeEvent>;
	onWillDispose: Event<void>;
	id: number;
	index: number;
	label: string;
	ariaLabel: string;
	activeEditorPane: import("../../../common/editor").IVisibleEditorPane | undefined;
	activeEditor: IEditorInput | null;
	previewEditor: IEditorInput | null;
	count: number;
	stickyCount: number;
	editors: readonly IEditorInput[];
	getEditors(order: EditorsOrder, options?: { excludeSticky?: boolean | undefined; } | undefined): readonly IEditorInput[] {
		throw new Error('Method not implemented.');
	}
	getEditorByIndex(index: number): IEditorInput | undefined {
		throw new Error('Method not implemented.');
	}
	getIndexOfEditor(editor: IEditorInput): number {
		throw new Error('Method not implemented.');
	}
	openEditor(editor: IEditorInput, options?: import("../../../../platform/editor/common/editor").IEditorOptions | ITextEditorOptions | undefined): Promise<import("../../../common/editor").IEditorPane | null> {
		throw new Error('Method not implemented.');
	}
	openEditors(editors: import("../../../common/editor").IEditorInputWithOptions[]): Promise<import("../../../common/editor").IEditorPane | null> {
		throw new Error('Method not implemented.');
	}
	isOpened(editor: IEditorInput): boolean {
		throw new Error('Method not implemented.');
	}
	isPinned(editor: IEditorInput): boolean {
		throw new Error('Method not implemented.');
	}
	isSticky(editorOrIndex: number | IEditorInput): boolean {
		throw new Error('Method not implemented.');
	}
	isActive(editor: IEditorInput): boolean {
		throw new Error('Method not implemented.');
	}
	moveEditor(editor: IEditorInput, target: IEditorGroup, options?: import("../../../services/editor/common/editorGroupsService").IMoveEditorOptions | undefined): void {
		throw new Error('Method not implemented.');
	}
	copyEditor(editor: IEditorInput, target: IEditorGroup, options?: import("../../../services/editor/common/editorGroupsService").ICopyEditorOptions | undefined): void {
		throw new Error('Method not implemented.');
	}
	closeEditor(editor?: IEditorInput | undefined, options?: import("../../../services/editor/common/editorGroupsService").ICloseEditorOptions | undefined): Promise<void> {
		throw new Error('Method not implemented.');
	}
	closeEditors(editors: IEditorInput[] | import("../../../services/editor/common/editorGroupsService").ICloseEditorsFilter, options?: import("../../../services/editor/common/editorGroupsService").ICloseEditorOptions | undefined): Promise<void> {
		throw new Error('Method not implemented.');
	}
	closeAllEditors(options?: import("../../../services/editor/common/editorGroupsService").ICloseAllEditorsOptions | undefined): Promise<void> {
		throw new Error('Method not implemented.');
	}
	replaceEditors(editors: import("../../../services/editor/common/editorGroupsService").IEditorReplacement[]): Promise<void> {
		throw new Error('Method not implemented.');
	}
	pinEditor(editor?: IEditorInput | undefined): void {
		throw new Error('Method not implemented.');
	}
	stickEditor(editor?: IEditorInput | undefined): void {
		throw new Error('Method not implemented.');
	}
	unstickEditor(editor?: IEditorInput | undefined): void {
		throw new Error('Method not implemented.');
	}
	focus(): void {
		throw new Error('Method not implemented.');
	}
	invokeWithinContext<T>(fn: (accessor: import("../../../../platform/instantiation/common/instantiation").ServicesAccessor) => T): T {
		throw new Error('Method not implemented.');
	}

}

closed time in 18 hours

bpasero

pull request commentmicrosoft/TypeScript

Process type nodes in codefixes/refactors for auto-imports recursively

!type || type.symbol was a weird hack to avoid stepping into nodes the function didn’t handle at the time; now that it knows how to handle everything recursively, I was able to remove it.

andrewbranch

comment created time in 18 hours

pull request commentTypeStrong/ts-loader

Support for symlinks in project references

Yep, I will do it this week if not today. 🚀

sheetalkamat

comment created time in 20 hours

delete branch andrewbranch/vscode-solidity

delete branch : patch-1

delete time in 2 days

delete branch andrewbranch/gatsby-remark-vscode

delete branch : dependabot/npm_and_yarn/examples/example-site/websocket-extensions-0.1.4

delete time in 3 days

push eventandrewbranch/gatsby-remark-vscode

dependabot[bot]

commit sha 0bdaa1866b38ea8e9edb4492e5346d5804abba11

Bump websocket-extensions from 0.1.3 to 0.1.4 in /examples/example-site (#103) Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

view details

push time in 3 days

PR merged andrewbranch/gatsby-remark-vscode

Bump websocket-extensions from 0.1.3 to 0.1.4 in /examples/example-site dependencies

Bumps websocket-extensions from 0.1.3 to 0.1.4. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md">websocket-extensions's changelog</a>.</em></p> <blockquote> <h3>0.1.4 / 2020-06-02</h3> <ul> <li>Remove a ReDoS vulnerability in the header parser (CVE-2020-7662, reported by Robert McLaughlin)</li> <li>Change license from MIT to Apache 2.0</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/faye/websocket-extensions-node/commit/8efd0cd6e35faf9bb9cb08759be1e27082177d43"><code>8efd0cd</code></a> Bump version to 0.1.4</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/3dad4ad44a8c5f74d4f8f4efd3f9d6e0b5df3051"><code>3dad4ad</code></a> Remove ReDoS vulnerability in the Sec-WebSocket-Extensions header parser</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/4a76c75efb1c5d6a2f60550e9501757458d19533"><code>4a76c75</code></a> Add Node versions 13 and 14 on Travis</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/44a677a9c0631daed0b0f4a4b68c095b624183b8"><code>44a677a</code></a> Formatting change: {...} should have spaces inside the braces</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/f6c50aba0c20ff45b0f87cea33babec1217ec3f5"><code>f6c50ab</code></a> Let npm reformat package.json</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/2d211f3705d52d9efb4f01daf5a253adf828592e"><code>2d211f3</code></a> Change markdown formatting of docs.</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/0b620834cc1e1f2eace1d55ab17f71d90d88271d"><code>0b62083</code></a> Update Travis target versions.</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/729a4653073fa8dd020561113513bfa2e2119415"><code>729a465</code></a> Switch license to Apache 2.0.</li> <li>See full diff in <a href="https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+13 -13

0 comment

1 changed file

dependabot[bot]

pr closed time in 3 days

delete branch andrewbranch/gatsby-remark-vscode

delete branch : default-colors

delete time in 3 days

push eventandrewbranch/gatsby-remark-vscode

Andrew Branch

commit sha 37eeb474133e53ba7471c4bd163215a9412c90e6

Pick a reasonable default for line highlight color based on theme background color (#106) * Detect dark themes by luminance * Fix dependencies * Update README * Update MIGRATING * Add test, adjust light default color * Ignore report.html * Don’t cache in GraphQL tests

view details

push time in 3 days

PR merged andrewbranch/gatsby-remark-vscode

Pick a reasonable default for line highlight color based on theme background color

Fixes #51

image

Light theme users will still probably want to pick their own, as I think this is pretty ugly, but it at least lets them know their configuration isn’t broken, which is the point of #51.

+2959 -29243

0 comment

31 changed files

andrewbranch

pr closed time in 3 days

push eventandrewbranch/gatsby-remark-vscode

Andrew Branch

commit sha b8770627e522310f187383f5c6a9f3dbb02e9533

Don’t cache in GraphQL tests

view details

push time in 3 days

push eventandrewbranch/gatsby-remark-vscode

Andrew Branch

commit sha 18789f0c87e0323577242188da46855cfb64ee78

Ignore report.html

view details

push time in 3 days

push eventandrewbranch/gatsby-remark-vscode

Andrew Branch

commit sha e13a4fde32af7b370e73bcff83676999b40b74ce

Add test, adjust light default color

view details

push time in 3 days

PR opened andrewbranch/gatsby-remark-vscode

Pick a reasonable default for line highlight color based on theme background color

Fixes #51

image

Light theme users will still probably want to pick their own, as I think this is pretty ugly, but it at least lets them know their configuration isn’t broken, which is the point of #51.

+1102 -26377

0 comment

25 changed files

pr created time in 3 days

push eventandrewbranch/gatsby-remark-vscode

Andrew Branch

commit sha 8b46c7c5f76c6c6c1e90202b57f0c65b384b8709

Update README

view details

Andrew Branch

commit sha 0449f7ff26f6408137bf04971e08c0beb3ee219f

Update MIGRATING

view details

push time in 3 days

PR opened juanfranblanco/vscode-solidity

npm script postinstall -> prepare

What

The npm postinstall script runs both on local npm install as well as after being installed as a dependency of someone else’s project. The prepare script only runs on local npm install (and before publishing). [npm-scripts]

Why

vscode is a devDependency, not a dependency, so if someone tries to install this package as a dependency of their own, the installation fails because ./node_modules/vscode does not exist.

Wait, what?

I’m the maintainer of gatsby-remark-vscode, a plugin for the Gatsby static site system that lets blog authors harness VS Code’s syntax highlighting engine to style their code blocks. Folks who are blogging about languages that aren’t included in VS Code’s default set of supported languages, like Solidity, can use GitHub repos like this to get syntax highlighting. Since the Visual Studio Marketplace is licensed for use only by Visual Studio products, I’m encouraging users to npm install any language and theme packages they need directly from GitHub (e.g. npm install juanfranblanco/vscode-solidity), provided the source is licensed appropriately. Unfortunately, that currently fails due to the postinstall script:

image

See also

https://github.com/styled-components/vscode-styled-components/pull/203

+1 -1

0 comment

1 changed file

pr created time in 3 days

push eventandrewbranch/vscode-solidity

Andrew Branch

commit sha b2fd53a2b255c99c0efc0835d6674aee5c73beaf

npm script postinstall -> prepare

view details

push time in 3 days

fork andrewbranch/vscode-solidity

Visual Studio Code language support extension for Solidity smart contracts in Ethereum

fork in 3 days

create barnchandrewbranch/gatsby-remark-vscode

branch : default-colors

created branch time in 3 days

issue commentcommonmark/commonmark-spec

Clarification of line endings in code blocks

Not really; at the time I was working on a Commonmark-compliant parser, and so wanted to get clarification for the purpose of my own implementation.

andrewbranch

comment created time in 3 days

issue commentandrewbranch/gatsby-remark-vscode

GraphQL API - styles missing

Huhhh, I honestly didn’t notice that childrenGrvscCodeBlock existed. I think I have some idea of why it might be behaving badly. Maybe I can prevent it from showing up, or if I rename grvscCodeBlocks to childrenGrvscCodeBlock it will behave better. This is good info for me to investigate. Thanks!

angeloashmore

comment created time in 3 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {

And maybe chainStartsWith(chain, subchain) is a clearer name for the function, since IIUC the subchain (currently called target) has to appear at the beginning of the chain (currently source), not just anywhere within it.

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {
+        while (isPropertyAccessExpression(source) && !isSyntacticMatch(source, target)) {
+            source = source.expression;
+        }
+        while (isPropertyAccessExpression(source) && isPropertyAccessExpression(target)) {
+            if (!isSyntacticMatch(source, target)) return false;
+            source = source.expression;
+            target = target.expression;
+        }
+        const fullMatch = isSyntacticMatch(source, target);
+        if (fullMatch && !isInJSFile(source)) {
+            Debug.assert(checker.getSymbolAtLocation(source) === checker.getSymbolAtLocation(target));
+        }
+        return fullMatch;

I guess the easiest to understand way to break it down, in my mind, would be to have a function that returns the array ["a", "b", "c", "d"] for the PropertyAccessExpression a.b.c.d (it could return strings or Identifiers, either way), then

function chainStartsWith(chain: EntityNameExpression, subchain: EntityNameExpression) {
  const subchainIdentifiers = getIdentifiersInEntityName(subchain);
  const chainIdentifiers = getIdentifiersInEntityName(chain);
  return every(subchain, (identifier, index) => {
    return identifier.getText() === chainIdentifiers[index]?.getText();
  });
}

This would be a bit more eager than what you have, and would allocate some arrays you don’t strictly need, but is easier to follow to me.

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {
+        while (isPropertyAccessExpression(source) && !isSyntacticMatch(source, target)) {
+            source = source.expression;
+        }
+        while (isPropertyAccessExpression(source) && isPropertyAccessExpression(target)) {
+            if (!isSyntacticMatch(source, target)) return false;
+            source = source.expression;
+            target = target.expression;
+        }
+        const fullMatch = isSyntacticMatch(source, target);
+        if (fullMatch && !isInJSFile(source)) {
+            Debug.assert(checker.getSymbolAtLocation(source) === checker.getSymbolAtLocation(target));
+        }
+        return fullMatch;

In this example I also presuppose the types EntityNameExpression to guarantee that you have a string of dot-separated identifiers, because it makes this function easier to reason about and there are already isEntityNameExpression functions you can use, but if you wanted to nitpick on efficiency, you could check on the fly in getIdentifiersInEntityName, returning undefined if you discover that you don’t actually have an EntityNameExpression.

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {
+        while (isPropertyAccessExpression(source) && !isSyntacticMatch(source, target)) {
+            source = source.expression;
+        }
+        while (isPropertyAccessExpression(source) && isPropertyAccessExpression(target)) {
+            if (!isSyntacticMatch(source, target)) return false;
+            source = source.expression;
+            target = target.expression;
+        }
+        const fullMatch = isSyntacticMatch(source, target);
+        if (fullMatch && !isInJSFile(source)) {
+            Debug.assert(checker.getSymbolAtLocation(source) === checker.getSymbolAtLocation(target));
+        }
+        return fullMatch;
+    }
+
+    function isSyntacticMatch(source: Node, target: Node): boolean {

This function appears to return true for a.b. and b.b; is that intentional?

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {

Maybe chain and subchain are better parameter names here; the meaning of source and target is fuzzy for me in this context.

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     function getOccurrencesInExpression(matchTo: Expression, expression: Expression, checker: TypeChecker): (PropertyAccessExpression | Identifier)[] | undefined {
         const occurrences: (PropertyAccessExpression | Identifier)[] = [];
         while (isBinaryExpression(expression) && expression.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
-            const match = checkMatch(matchTo, expression.right, checker);
+            const match = getMatchingSubexpression(matchTo, expression.right, checker);
             if (!match) {
                 break;
             }
             occurrences.push(match);
             matchTo = match;
             expression = expression.left;
         }
-        const finalMatch = checkMatch(matchTo, expression, checker);
+        const finalMatch = getMatchingSubexpression(matchTo, expression, checker);
         if (finalMatch) {
             occurrences.push(finalMatch);
         }
         return occurrences.length > 0 ? occurrences: undefined;
     }
 
     /**
-     * Checks that expression is a subchain of matchTo.
+     * Checks that expression is a syntactic subexpression of matchTo.
      */
-    function checkMatch(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
+    function getMatchingSubexpression(matchTo: Expression, expression: Expression, checker: TypeChecker): PropertyAccessExpression | Identifier | undefined {
         if (isCallExpression(matchTo)) {
-            // Recurse through the call expressions to match a.b to a.b()().
-            return !isCallExpression(expression) ? checkMatch(matchTo.expression, expression, checker) : undefined;
+            return !isCallExpression(expression) ? getMatchingSubexpression(matchTo.expression, expression, checker) : undefined;
         }
         else if ((isPropertyAccessExpression(expression) || isIdentifier(expression)) && (isPropertyAccessExpression(matchTo) || isIdentifier(matchTo))) {
-            return checker.isOrContainsMatchingReference(matchTo, expression) ? expression : undefined;
+            return containsSyntacticSubchain(matchTo, expression, checker) ? expression : undefined;
         }
         return undefined;
     }
 
+    /**
+     * Returns true if target is a syntactic subchain of source.
+     */
+    function containsSyntacticSubchain(source: Node, target: Node, checker: TypeChecker): boolean {
+        while (isPropertyAccessExpression(source) && !isSyntacticMatch(source, target)) {
+            source = source.expression;
+        }
+        while (isPropertyAccessExpression(source) && isPropertyAccessExpression(target)) {
+            if (!isSyntacticMatch(source, target)) return false;
+            source = source.expression;
+            target = target.expression;
+        }
+        const fullMatch = isSyntacticMatch(source, target);
+        if (fullMatch && !isInJSFile(source)) {
+            Debug.assert(checker.getSymbolAtLocation(source) === checker.getSymbolAtLocation(target));
+        }
+        return fullMatch;

I think there’s possibly a less efficient but more easily understandable way to write this function by going depth-first, grabbing the left-most name of both the chain and the subchain right away, and walking up their parents. But I couldn’t write an elegant example in a few minutes, so maybe it wouldn’t be as good as I think it would.

jessetrinity

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

 namespace ts.refactor.convertToOptionalChainExpression {     }
 
     /**
-     * Gets the right-most property access expression.
+     * Gets a property access expression which may be nested inside of a call expression or binary expression. The final
+     * expression in an && chain will occur as the right child of the parent binary expression, unless it is a call expression
+     * or is followed by a different binary operator.
+     * @param node the right child of a binary expression or a call expression.
      */
     function getLastPropertyAccessChain(node: Expression): PropertyAccessExpression | undefined {
+        // foo && |foo.bar === 1|; - here the right child of the && binary expression is another binary expression.
+        // the rightmost member of the && chain should be the leftmost child of that expression.
         if (isBinaryExpression(node)) {

You should also node = skipParentheses(node) at the top here

jessetrinity

comment created time in 6 days

pull request commentmicrosoft/TypeScript

Typeof coud narrow union type with property

@typescript-bot test this @typescript-bot user test this @typescript-bot perf test this

ShuiRuTian

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Typeof coud narrow union type with property

 namespace ts {                 return type;
             }
 
+            // return true only when it is a access expression and has ?.
+            function isAccessExpressionContainOptionalChain(e: UnaryExpression) {
+                while (isAccessExpression(e)) {
+                    if (e.flags & NodeFlags.OptionalChain) {
+                        return true;
+                    }
+                    e = e.expression;
+                }
+                return false;
+            }
+
+            /**
+             * @param optionalChainSlice If this is true, only match the part before first optional chain. if expression is a.b.c?.d.e, only take a.b.c to get property.
+             */
+            function getPropertyTypesFromTypeAccordingToExpression(type: Type, expressionWithOutKeyword: Expression, optionalChainSlice = false): Type[] | undefined {
+                // This function is designed to be used in the first steps in follow steps:
+                // 1. get all properties' type of the origional types according to expression path
+                //   - In some case, should not narrow type according to the whole path, for example:
+                //   - typeof a.b?.c.d? !== number, === undefined, !==undefined, when we come to a, its type could only be narrowed by a.b.
+                //   - But for typeof a.b?.c.d? === number, when we come to a, it could be narrowed by the full path.
+                // 2. use expression to mark wanted types as 'true'
+                // 3. use the mark to get narrowed type from origional type.
+
+                function tryGetPropertyPathsOfReferenceFromExpression(expressionOri: Expression, _ref?: Node) {
+                    function getTypeDepthIfMatch(expression: Expression, ref: Node): number {
+                        let result = 0;
+                        let expr = expression;
+                        if (isMatchingReference(ref, expr)) {
+                            return result;
+                        }
+                        while (isAccessExpression(expr)) {
+                            result = result + 1;
+                            expr = expr.expression;
+                            if (isMatchingReference(ref, expr)) {
+                                return result;
+                            }
+                        }
+                        return -1;
+                    }
+
+                    // If expression is a, return []
+                    // If expression is a.b["c"].d(), return ["b","c","d"]
+                    // NOTE: If element expression is not known in compile progress like a.b[f()].d, the result would be undefined
+                    // //NOTE: this function need improvement, ElementAccessExpression argument might could be known in compile time, like "1"+"2", we should check "12" in the path, but how to get the value?
+                    function getPropertyPathsOfAccessExpression(expressionOri: Expression, depth: number): __String[] | undefined {

We should unnest functions that don’t close over anything from their out scopes as much as possible. This one looks like it doesn’t close over anything at all.

ShuiRuTian

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Typeof coud narrow union type with property

 namespace ts {                 return isMatchingReference(reference, expr.expression) && isDiscriminantProperty(type, name);
             }
 
-            function narrowTypeByDiscriminant(type: Type, access: AccessExpression, narrowType: (t: Type) => Type): Type {
+            function isMatchingReferenceDiscriminantNew(expr: Expression, computedType: Type) {
+                // main part is copied from function createUnionOrIntersectionProperty
+                function isTypeArrayDiscriminant(types: Type[], nullableFlag = false) {
+                    let checkFlags = 0;
+                    let firstType: Type | undefined;
+                    for (const type of types) {
+                        if (nullableFlag && (type.flags & TypeFlags.Nullable)){
+                            continue;
+                        }
+                        if (!firstType) {
+                            firstType = type;
+                        }
+                        else if (type !== firstType) {
+                            checkFlags |= CheckFlags.HasNonUniformType;
+                        }
+                        if (isLiteralType(type)) {
+                            checkFlags |= CheckFlags.HasLiteralType;
+                        }
+                        if (type.flags & TypeFlags.Never) {
+                            checkFlags |= CheckFlags.HasNeverType;
+                        }
+                    }
+                    // next line is copied from isDiscriminantProperty
+                    return (checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant && !maybeTypeOfKind(getUnionType(types), TypeFlags.Instantiable);;
                    return (checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant && !maybeTypeOfKind(getUnionType(types), TypeFlags.Instantiable);
ShuiRuTian

comment created time in 6 days

Pull request review commentmicrosoft/TypeScript

Typeof coud narrow union type with property

+tests/cases/conformance/expressions/typeGuards/typeGuardAccordingToProperty.ts(66,11): error TS2339: Property 'b1' does not exist on type 'Boolean1 | Boolean2'.
+  Property 'b1' does not exist on type 'Boolean2'.
+tests/cases/conformance/expressions/typeGuards/typeGuardAccordingToProperty.ts(67,11): error TS2339: Property 'b2' does not exist on type 'Boolean1 | Boolean2'.
+  Property 'b2' does not exist on type 'Boolean1'.
+tests/cases/conformance/expressions/typeGuards/typeGuardAccordingToProperty.ts(80,11): error TS2339: Property 'b1' does not exist on type 'Boolean1 | Boolean2'.
+  Property 'b1' does not exist on type 'Boolean2'.
+tests/cases/conformance/expressions/typeGuards/typeGuardAccordingToProperty.ts(81,11): error TS2339: Property 'b2' does not exist on type 'Boolean1 | Boolean2'.
+  Property 'b2' does not exist on type 'Boolean1'.
+
+
+==== tests/cases/conformance/expressions/typeGuards/typeGuardAccordingToProperty.ts (4 errors) ====
+    // Primitive value ---- boolean bigint number string symbol undefined function object
+    // ts special type ---- any, void, unknown, union, intersection
+    
+    //// Property Access ---- a.b
+    //// Element Access ---- a["b"]
+    
+    interface Boolean1 {
+        key: boolean;
+        b1: number;
+    };
+    
+    interface Boolean2 {
+        key: boolean;
+        b2: number;
+    };
+    
+    interface BigInt1 {
+        key: bigint;
+        bi1: number;
+    };
+    
+    interface Number1 {
+        key: number;
+        n1: number;
+    };
+    
+    interface String1 {
+        key: string;
+        st1: number;
+    }
+    
+    interface Symbol1 {
+        key: symbol;
+        sy1: number;
+    }
+    
+    interface Undefined1 {
+        key: undefined;
+        u1: number;
+    }
+    
+    interface Function1 {
+        key: () => void;
+        f1: number;
+    }
+    
+    interface Obejct1 {
+        key: {
+            notEmpty: number;
+        };
+        o1: number;
+    }
+    
+    type Union1 = Boolean1 | Boolean2 | Number1;
+    type Union2 = Boolean1 | BigInt1 | Number1 | String1 | Symbol1 | Undefined1 | Function1 | Obejct1;
+    
+    function f1_1(u: Union1) {
+        if (typeof u.key !== 'boolean') {
+            u;      // Number1
+            u.n1;   // number
+        }
+    }
+    function f1_2(u: Union1) {
+        if (typeof u.key === 'boolean') {
+            u;      // Bolean1 | Bolean2
+            u.b1;   // Error
+              ~~
+!!! error TS2339: Property 'b1' does not exist on type 'Boolean1 | Boolean2'.
+!!! error TS2339:   Property 'b1' does not exist on type 'Boolean2'.
+            u.b2;   // Error
+              ~~
+!!! error TS2339: Property 'b2' does not exist on type 'Boolean1 | Boolean2'.
+!!! error TS2339:   Property 'b2' does not exist on type 'Boolean1'.
+        }
+    }
+    
+    function f1ElementAccess_1(u: Union1) {
+        if (typeof u["key"] !== 'boolean') {
+            u;      // Number1
+            u.n1;   // number
+        }
+    }
+    function f1ElementAccess_2(u: Union1) {
+        if (typeof u["key"] === 'boolean') {
+            u;      // Bolean1 | Bolean2
+            u.b1;   // Error
+              ~~
+!!! error TS2339: Property 'b1' does not exist on type 'Boolean1 | Boolean2'.
+!!! error TS2339:   Property 'b1' does not exist on type 'Boolean2'.
+            u.b2;   // Error
+              ~~
+!!! error TS2339: Property 'b2' does not exist on type 'Boolean1 | Boolean2'.
+!!! error TS2339:   Property 'b2' does not exist on type 'Boolean1'.
+        }
+    }
+    
+    function f1_Plus(u: Union1) {
+        if (typeof u.key !== 'boolean') {
+            throw new Error();
+        }
+        u;  // Bolean1 | Bolean2
+        if (typeof u.key === 'boolean') {
+            throw new Error();
+        }
+        u;  // never
+    }
+    
+    // boolean bigint number string symbol undefined function object
+    function f2_1(u: Union2) {
+        if (typeof u.key === 'bigint') {
+            u;      // BigInt1
+            u.bi1;
+        }
+        if (typeof u.key == 'bigint') {
+            u;      // BigInt1
+            u.bi1;
+        }
+    }
+    function f2_2(u: Union2) {
+        if (typeof u.key === 'boolean') {
+            u;      // Boolean1
+            u.b1;
+        }
+        if (typeof u.key == 'boolean') {
+            u;      // Boolean1
+            u.b1;
+        }
+    }
+    function f2_3(u: Union2) {
+        if (typeof u.key === 'number') {
+            u;      // Number1
+            u.n1;
+        }
+        if (typeof u.key == 'number') {
+            u;      // Number1
+            u.n1;
+        }
+    }
+    function f2_4(u: Union2) {
+        if (typeof u.key === 'string') {
+            u;      // String1
+            u.st1;
+        }
+        if (typeof u.key == 'string') {
+            u;      // String1
+            u.st1;
+        }
+    }
+    function f2_5(u: Union2) {
+        if (typeof u.key === 'symbol') {
+            u;      // Symbol1
+            u.sy1;
+        }
+        if (typeof u.key == 'symbol') {
+            u;      // Symbol1
+            u.sy1;
+        }
+    }
+    function f2_6(u: Union2) {
+        if (typeof u.key === 'undefined') {
+            u;      // Undefined1
+            u.u1
+        }
+        if (typeof u.key == 'undefined') {
+            u;      // Undefined1
+            u.u1
+        }
+    }
+    function f2_7(u: Union2) {
+        if (typeof u.key === 'function') {
+            u;      // Function1
+            u.f1;
+        }
+        if (typeof u.key == 'function') {
+            u;      // Function1
+            u.f1;
+        }
+    }
+    function f2_8(u: Union2) {
+        if (typeof u.key === 'object') {
+            u;      // Object1
+            u.o1;
+        }
+        if (typeof u.key == 'object') {
+            u;      // Object1
+            u.o1;
+        }
+    }
+    
+    function f2Not_1(u: Union2) {
+        if (typeof u.key !== 'bigint') {
+            u;      // not BigInt1
+        }
+        if (typeof u.key != 'bigint') {
+            u;      // not BigInt1
+        }
+    }
+    function f2Not_2(u: Union2) {
+        if (typeof u.key !== 'boolean') {
+            u;      // not Boolean1
+        }
+        if (typeof u.key != 'boolean') {
+            u;      // not Boolean1
+        }
+    }
+    
+    function f2Not_3(u: Union2) {
+        if (typeof u.key !== 'number') {
+            u;      // not Number1
+        }
+        if (typeof u.key != 'number') {
+            u;      // not Number1
+        }
+    }
+    
+    function f2Not_4(u: Union2) {
+        if (typeof u.key !== 'string') {
+            u;      // not String1
+        }
+        if (typeof u.key != 'string') {
+            u;      // not String1
+        }
+    }
+    
+    function f2Not_5(u: Union2) {
+        if (typeof u.key !== 'symbol') {
+            u;      // not Symbol1
+        }
+        if (typeof u.key != 'symbol') {
+            u;      // not Symbol1
+        }
+    }
+    
+    function f2Not_6(u: Union2) {
+        if (typeof u.key !== 'undefined') {
+            u;      // not Undefined1
+        }
+        if (typeof u.key != 'undefined') {
+            u;      // not Undefined1
+        }
+    }
+    
+    function f2Not_7(u: Union2) {
+        if (typeof u.key !== 'function') {
+            u;      // not Function1
+        }
+        if (typeof u.key != 'function') {
+            u;      // not Function1
+        }
+    }
+    
+    function f2Not_8(u: Union2) {
+        if (typeof u.key !== 'object') {
+            u;      // not Object1
+        }
+        if (typeof u.key != 'object') {
+            u;      // not Object1
+        }
+    }
+    
+    interface A { x: string, y: string };
+    interface B { x: number, y: number };
+    type X = A | B;
+    
+    function f3(bar: X) {
+        if (typeof bar.x === 'string') {
+            let y = bar.y; // string
+        }
+    }
+    
+    /////////////////////////////////////////////////////////
+    //  some case that need discuss further, This is not that right.
+    function f1_(u: Union1) {
+        const tmp1 = u.key;
+        if (typeof tmp1 !== 'boolean') {
+            u;          //Union1
+            u.key;      //number | boolean
+        }
+    }

This is a well-known limitation; it’s not a problem in the context of this PR.

ShuiRuTian

comment created time in 6 days

PR opened microsoft/TypeScript

Reviewers
Insert auto-imports in sorted order

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #33839

When import declarations/specifiers are already sorted, we insert new declarations/specifiers in the appropriate location. The sort order of import specifiers is alphabetical (reusing the existing logic from organize imports). The sort order for import declarations is alphabetical by module specifier, with module specifier ties being broken by the secondary sort order:

  1. Side-effect imports
  2. Type-only imports
  3. Namespace imports
  4. Default imports
  5. Named imports
  6. ImportEqualsDeclarations
  7. Require variable statements

The organize imports logic has been updated to use that tiebreaker as well.

+254 -134

0 comment

51 changed files

pr created time in 6 days

push eventandrewbranch/TypeScript

Andrew Branch

commit sha c92b071b1d3b580ee50c7b76ed506e96d0953994

Avoid re-checking sort all the time

view details

push time in 6 days

create barnchandrewbranch/TypeScript

branch : feature/33839

created branch time in 6 days

pull request commentmicrosoft/TypeScript

allow consecutive newlines in jsdoc tag comments

@typescript-bot pack this

orokanasaru

comment created time in 6 days

delete branch andrewbranch/TypeScript

delete branch : launch-update

delete time in 7 days

PR closed microsoft/TypeScript

Update launch.template.json for new node debugger Author: Team

Without this, the new debugger won’t respect the “Auto-expand getters” setting, which makes debugging the TS codebase a huge pain: https://github.com/microsoft/vscode-js-debug/issues/447#issuecomment-639619286

+2 -3

1 comment

1 changed file

andrewbranch

pr closed time in 7 days

PR opened microsoft/TypeScript

Fix getTypeAtLocation for dotted implements clauses

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #37901

+30 -1

0 comment

2 changed files

pr created time in 7 days

create barnchandrewbranch/TypeScript

branch : bug/37901

created branch time in 7 days

Pull request review commentmicrosoft/TypeScript

Add refactor convertToOptionalChainExpression

+/// <reference path='fourslash.ts' />
+
+/////*a*/foo && foo.bar;/*b*/
+
+// Do not offer refactor for unknown symbols.

You’d have to use syntax here, not symbols.

jessetrinity

comment created time in 7 days

pull request commentmicrosoft/TypeScript

Update launch.template.json for new node debugger

This might be unnecessary after the next VS Code release, I'm waiting for clarification at https://github.com/microsoft/vscode-js-debug/issues/447

andrewbranch

comment created time in 7 days

Pull request review commentDefinitelyTyped/DefinitelyTyped

typings for @rdfjs/term-map

+// Type definitions for @rdfjs/term-map 1.0+// Project: https://github.com/rdfjs-base/term-map+// Definitions by: tpluscode <https://github.com/tpluscode>+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped++import { Term } from "rdf-js";++interface TermMap<T extends Term = Term, V = any> extends Map<T, V> {+}++// tslint:disable-next-line no-unnecessary-class+declare class TermMap<T extends Term = Term, V = any> {+    constructor(entries?: Array<[Term, V]>);+}

Extending Map<T, V> is what lets you avoid repeating members (note I moved the heritage clause to the class declaration in my suggestion). Declaration merging lets you treat multiple declarations as a single symbol (which in fact is exactly what happens under the hood). Sorry I didn’t look far enough ahead to realize in my earlier review that the interface was going to be useless. When I said

There’s no reason to distinguish between the interface and the class—that’s the whole point of declaration merging.

what I meant was that it is not possible to “distinguish” between multiple merged declarations, because each declaration simply contributes to a shared symbol. What you reference is that shared symbol, and the symbol takes on the meanings and members of all its constituent declarations.

To illustrate, here’s a simplified representation of how the merging works for the code as-is:

// Meanings: Type (i.e., can be used in a type position, not in a value or namespace position)
// Members: { ...inherit from Map<T, V> }
interface TermMap<T extends Term = Term, V = any> extends Map<T, V> {
}

// Meanings: Type | Value (can be used as a type, but also as a value, as in `new TermMap()`)
// Members: {}
declare class TermMap<T extends Term = Term, V = any> {
    constructor(entries?: Array<[Term, V]>);
}

/* MERGE RESULT */
// Meanings: Type | Value
// Members: { ...inherit from Map<T, V> }

But you can notice that this distribution of meanings and members has some redundancy. The class contributes no members, and the interface contributes no meanings that the class didn’t already have. The interface cannot possibly take on a value meaning (much less one with a constructor), but the class can certainly take on the members that the interface contributes. By moving the extends Map<T, V> from the interface declaration to the class declaration, the class declaration is now

// Meanings: Type | Value
// Members: { ...inherit from Map<T, V> }
declare class TermMap<T extends Term = Term, V = any> extends Map<T, V> {
    constructor(entries?: Array<[Term, V]>);
}

which, in a single declaration, has the exact same meanings and members as the merged symbol from before. So, there’s no reason to split them up into two declarations.

Again, sorry I didn’t look two steps ahead to avoid this intermediate revision. Hope this clears things up.

tpluscode

comment created time in 7 days

issue commentandrewbranch/gatsby-remark-vscode

GraphQL API - styles missing

Could there be an async problem somewhere in the code?

Yes there definitely could; if you can track down a reliable repro of the style element being included in grvscCodeBlocks { html }, I would be very interested to see that.

angeloashmore

comment created time in 8 days

issue commentandrewbranch/gatsby-remark-vscode

GraphQL API - styles missing

If I edit a query and save, likely causing Gatsby to rerun queries, the style element is included

Really? I don’t think the style element should ever be included in that query 😅

There’s a separate top-level resolver for the stylesheet, but I should have made it a child of MarkdownRemark too. Thanks for bringing that up; I’ll add it before releasing v3.

In the meantime, you should be able to get the stylesheet content with this:

query {
  grvscStylesheet {
    css
  }
}

grvscStylesheet takes optional arguments:

  • defaultTheme: String
  • additionalThemes: [GRVSCThemeArgument!]
  • injectStyles: Boolean

but absent those, it will use the plugin configuration in gatsby-node, which is probably what you want.

angeloashmore

comment created time in 8 days

issue closedmicrosoft/TypeScript

auto imports are broken with yarn PNP on Windows

Issue Type: <b>Bug</b>

I haven't changed my settings at all, but after upgrading to the newest patch my imports and suggestions no longer show which package the import recommendation is coming from. Say I have 2 Configurations and I want to auto-import the one from webpack, it should say which package the current suggestion comes from, and when hitting ENTER it doesn't import, but rather just finishes the line.

Screenshot_7

VS Code version: Code 1.46.1 (cd9ea6488829f560dc949a8b2fb789f3cdc05f5d, 2020-06-17T21:13:20.174Z) OS version: Windows_NT x64 10.0.18363

<details> <summary>System Info</summary>

Item Value
CPUs Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz (8 x 1896)
GPU Status 2d_canvas: enabled<br>flash_3d: enabled<br>flash_stage3d: enabled<br>flash_stage3d_baseline: enabled<br>gpu_compositing: enabled<br>multiple_raster_threads: enabled_on<br>oop_rasterization: disabled_off<br>protected_video_decode: enabled<br>rasterization: enabled<br>skia_renderer: disabled_off_ok<br>video_decode: enabled<br>viz_display_compositor: enabled_on<br>viz_hit_test_surface_layer: disabled_off_ok<br>webgl: enabled<br>webgl2: enabled
Load (avg) undefined
Memory (System) 7.92GB (1.60GB free)
Process Argv C:\Users\adria\Desktop\Grim\projects\yarnberry-toolkit
Screen Reader no
VM 0%

</details><details><summary>Extensions (30)</summary>

Extension Author (truncated) Version
better-comments aar 2.0.5
vscode-zipfs arc 2.0.0
github-markdown-preview bie 0.0.2
markdown-checkbox bie 0.1.3
markdown-emoji bie 0.0.9
markdown-preview-github-styles bie 0.1.6
markdown-yaml-preamble bie 0.0.4
vscode-eslint dba 2.1.5
javascript-ejs-support Dig 1.3.1
gitlens eam 10.2.2
vsc-material-theme Equ 32.8.0
vsc-material-theme-icons equ 1.1.4
prettier-vscode esb 5.1.0
vscode-systemd-support han 0.1.1
vscode-docker ms- 1.3.1
vscode-kubernetes-tools ms- 1.2.1
remote-containers ms- 0.122.1
remote-ssh ms- 0.51.0
remote-ssh-edit ms- 0.51.0
remote-wsl ms- 0.44.4
vscode-remote-extensionpack ms- 0.20.0
vscode-markdown-notebook ms- 0.0.7
debugger-for-chrome msj 4.12.8
env-cmd-file-syntax Nix 0.1.2
material-icon-theme PKi 4.2.0
vscode-xml red 0.12.0
vscode-yaml red 0.8.0
code-spell-checker str 1.9.0
vscodeintellicode Vis 1.2.8
vscode-nginx wil 0.7.2

(1 theme extensions excluded)

</details> <!-- generated by issue reporter -->

closed time in 8 days

TheGrimSilence

issue commentmicrosoft/TypeScript

auto imports are broken with yarn PNP on Windows

I use https://getkap.co, which is macOS-only unfortunately.

Ok, so I’ve tracked this down to be the fault of yarn’s wrapper around TypeScript. It’s intercepting messages to TS Server, deserializing them, looking for file paths, modifying those paths before passing them on. Unfortunately, it seems to be doing this incorrectly on Windows, at least some of the time. First, when we send back the full list of completions, the Configuration item looks like this on the server:

{
  "name": "Configuration",
  "kind": "interface",
  "kindModifiers": "declare",
  "sortText": "5",
  "hasAction": true,
  "source": "c:/Users/andrew/yarnberry-toolkit/.yarn/cache/@types-webpack-npm-4.41.18-f868232c99-43fefaccab.zip/node_modules/@types/webpack/index"
}

The TS Server wrapper sees the path with .zip in it, and does some processing to serialize it like this (note the zip:/ prefix on source) before sending it to the client:

{
  "name": "Configuration",
  "kind": "interface",
  "kindModifiers": "declare",
  "sortText": "5",
  "hasAction": true,
  "source": "zip:/c:/Users/andrew/yarnberry-toolkit/.yarn/cache/@types-webpack-npm-4.41.18-f868232c99-43fefaccab.zip/node_modules/@types/webpack/index"
}

Now, when you highlight that item in VS Code, we make another request to get the details for that completion item. That request includes the name and source we got from the last response. The raw incoming message looks like this:

{
  "seq": 53,
  "type": "request",
  "command": "completionEntryDetails",
  "arguments": {
    "file": "c:/Users/andrew/yarnberry-toolkit/src/tools/BaseCommand.ts",
    "line": 4,
    "offset": 18,
    "entryNames": [
      {
        "name": "Configuration",
        "source": "zip:/c:/Users/andrew/yarnberry-toolkit/.yarn/cache/@types-webpack-npm-4.41.18-f868232c99-43fefaccab.zip/node_modules/@types/webpack/index"
      }
    ]
  }
}

However, before sending it on to TS Server proper, the wrapper notices the zip:/ path and changes the response to this:

{
  "seq": 53,
  "type": "request",
  "command": "completionEntryDetails",
  "arguments": {
    "file": "c:/Users/andrew/yarnberry-toolkit/src/tools/BaseCommand.ts",
    "line": 4,
    "offset": 18,
    "entryNames": [
      {
        "name": "Configuration",
        "source": "/c:/Users/andrew/yarnberry-toolkit/.yarn/cache/@types-webpack-npm-4.41.18-f868232c99-43fefaccab.zip/node_modules/@types/webpack/index"
      }
    ]
  }
}

Uh oh! Now we’ve wound up with a superfluous leading slash on that source. The rest of the process entails trying to match up existing module specifiers with that source, which we will obviously not be able to do so it’s been mangled.

So yep, this is a yarn bug.

TheGrimSilence

comment created time in 8 days

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

Yep, it repros for me on Windows. Thanks for the help!

TheGrimSilence

comment created time in 8 days

issue commentmicrosoft/vscode-js-debug

Add option to show getter evaluation without expanding

I’m already using VS Code Insiders, so my understanding was I’m already using the new debugger, and yet my preferences weren’t being used until changing the launch config type. But I could be misunderstanding something. What is pwa-node? Is it something that will be phased out after the next release? (Practically speaking, is this PR misinformed?)

andrewbranch

comment created time in 8 days

pull request commentmicrosoft/TypeScript

Improve inference for Promise.all of 'never[]'

There’s one relevant change: https://github.com/typescript-bot/TypeScript/pull/54/files#diff-ce8b151b649148d02935b814380073d7

rbuckton

comment created time in 8 days

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

For the brief time that I had a Surface Book, I was frequently concerned for the safety of pedestrians walking underneath my office window 🙊

TheGrimSilence

comment created time in 8 days

issue commentmicrosoft/vscode-js-debug

Add option to show getter evaluation without expanding

@connor4312 is there going to be an obvious migration path for people who have existing "node" launch configurations? Without your comment here, I would have never figured out that I needed to update mine. I assumed the auto-expand getters option was just broken.

andrewbranch

comment created time in 8 days

PR opened microsoft/TypeScript

Update launch.template.json for new node debugger

Without this, the new debugger won’t respect the “Auto-expand getters” setting, which makes debugging the TS codebase a huge pain: https://github.com/microsoft/vscode-js-debug/issues/447#issuecomment-639619286

+2 -3

0 comment

1 changed file

pr created time in 8 days

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

I'll try to give a try on Windows to see if that makes a difference.

TheGrimSilence

comment created time in 8 days

create barnchandrewbranch/TypeScript

branch : launch-update

created branch time in 8 days

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

Kapture 2020-06-30 at 15 25 11

Seems to work for me; am I missing something obvious here?

TheGrimSilence

comment created time in 8 days

Pull request review commentmicrosoft/TypeScript

Emit fallback for decorator metadata for type only imports

 namespace ts {             }
 
             // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
-            const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
+            const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location);
+            const isTypeOnly = valueSymbol?.declarations?.every(isTypeOnlyImportOrExportDeclaration) || false;
+            const resolvedSymbol = valueSymbol && valueSymbol.flags & SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol;
 
             // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
             const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
-            if (valueSymbol && valueSymbol === typeSymbol) {
+            if (resolvedSymbol && resolvedSymbol === typeSymbol) {
                 const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
-                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
+                if (globalPromiseSymbol && resolvedSymbol === globalPromiseSymbol) {
                     return TypeReferenceSerializationKind.Promise;
                 }
 
-                const constructorType = getTypeOfSymbol(valueSymbol);
+                const constructorType = getTypeOfSymbol(resolvedSymbol);
                 if (constructorType && isConstructorType(constructorType)) {
-                    return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
+                    return isTypeOnly ? TypeReferenceSerializationKind.TypeWithCallSignature : TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
                 }
             }
 
             // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
             if (!typeSymbol) {
-                return TypeReferenceSerializationKind.Unknown;
+                return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown;

How do we know the type is objecty? You can import type a primitive.

rbuckton

comment created time in 8 days

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

Would you be able to provide either an example repo or step-by-step instructions on how to create a simple reproduction of the problem? Where does that version of TypeScript live? In order for VS Code to use it, you’d have to point to it in .vscode/settings.json. Do you have a custom typescript.tsdk entry in there? Or is there a VS Code extension that’s required for editor operations to work properly with PNP?

TheGrimSilence

comment created time in 8 days

Pull request review commentDefinitelyTyped/DefinitelyTyped

typings for @rdfjs/term-map

+// Type definitions for @rdfjs/term-map 1.0+// Project: https://github.com/rdfjs-base/term-map+// Definitions by: tpluscode <https://github.com/tpluscode>+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped++import { Term } from "rdf-js";++interface TermMap<T extends Term = Term, V = any> extends Map<T, V> {+}++// tslint:disable-next-line no-unnecessary-class+declare class TermMap<T extends Term = Term, V = any> {+    constructor(entries?: Array<[Term, V]>);+}
declare class TermMap<T extends Term = Term, V = any> extends Map<T, V> {
    constructor(entries?: Array<[Term, V]>);
}
tpluscode

comment created time in 8 days

pull request commentmicrosoft/TypeScript

Improve inference for Promise.all of 'never[]'

Makes sense to me, but should we run user tests?

@typescript-bot user test this

rbuckton

comment created time in 8 days

push eventmicrosoft/TypeScript

Andrew Branch

commit sha e2c5a90cc3bcbc0ea78e13bf0f5b889a2aed8248

Disable signature help on unresolved bare identifiers; add more declaration info on other unresolved calls (#39352) * Disable signature help on unresolved bare identifiers; add more declaration info on unresolvedproperty access * Remove stray ts-ignore

view details

push time in 8 days

PR merged microsoft/TypeScript

Reviewers
Disable signature help on unresolved bare identifiers; add more declaration info on other unresolved calls Author: Team

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #33565

Before After
image image
image image
+41 -4

0 comment

3 changed files

andrewbranch

pr closed time in 8 days

issue closedmicrosoft/TypeScript

Unexpected parameter hint showing up for `log` in js file

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

From https://github.com/microsoft/vscode/issues/80565

<!-- Please try to reproduce the issue with typescript@next. It may have already been fixed. --> TypeScript Version: 3.7.20190922

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms:

  • javascript
  • parameter hints / signature help

Code In a js file:

//@ts-check

log(

Trigger parameter hints on log

Expected behavior: Nothing shows up. log is undefined here and you can't run go to definition on it

Actual behavior: Screen Shot 2019-09-23 at 11 59 10 AM

Playground Link: <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->

Related Issues: <!-- Did you find other bugs that looked similar? -->

closed time in 8 days

mjbvz

issue commentmicrosoft/TypeScript

auto imports are broken (Yarn PnP issue probably)

@TheGrimSilence can you grab the TS Server log generated during that action? Also, can you try this with the JS/TS Nightly extension if you haven’t already?

TheGrimSilence

comment created time in 8 days

push eventandrewbranch/TypeScript

Andrew Branch

commit sha c5b70d9623934c13067da7016d907a47d108b30a

Remove stray ts-ignore

view details

push time in 8 days

PR opened microsoft/TypeScript

Disable signature help on unresolved bare identifiers; add more declaration info on other unresolved calls

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #33565

Before After
image image
image image
+41 -4

0 comment

3 changed files

pr created time in 8 days

create barnchandrewbranch/TypeScript

branch : bug/33565

created branch time in 8 days

pull request commentmicrosoft/TypeScript

Typeof coud narrow union type with property

Thanks for putting this together @ShuiRuTian! I looked through a bunch of the changed test baselines last week, and my suspicion is that this change is going to be too big for 4.0 now that we’ve released the beta (we try not to add any big features or breaking changes during this period). I’m on DefinitelyTyped duty this week, but will try to give this a more careful review next week and discuss with the team. Just wanted to set expectations that even if all the changes look perfect, we may decide it needs to wait until 4.1. Thanks again!

ShuiRuTian

comment created time in 9 days

push eventmicrosoft/TypeScript

Alexander T

commit sha ee5c3fa57df274d824225cc3c17fd2d47cc67f63

fix(39047): handle extra spaces after the catch statement (#39306)

view details

push time in 9 days

issue closedmicrosoft/TypeScript

Default formatter cant format JS Optional catch binding properly

TS Template added by @mjbvz

TypeScript Version: 4.0.0-dev.20200611

Search Terms

  • format / formatting
  • try/catch

Issue Type: <b>Bug</b>

Reproduction code:

"use strict";
try {
    throw new Error();
} catch        {
    console.info("Hello world");
}

Expected behaviour: When vscode tried formatting the code, the extra spaces should be removed.

What happend: The extra spaces can not be removed via formatting. (But when I put () in spaces, formatter can format the code properly.) Does this issue occur when all extensions are disabled?: Yes Does this issue occur on Insider build?: Yes

My vscode setting: "editor.defaultFormatter": null

VS Code version: Code 1.46.0 (a5d1cc28bb5da32ec67e86cc50f84c67cc690321, 2020-06-10T09:03:20.462Z) OS version: Windows_NT x64 10.0.19041

<details> <summary>System Info</summary>

Item Value
CPUs Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz (4 x 2592)
GPU Status 2d_canvas: enabled<br>flash_3d: enabled<br>flash_stage3d: enabled<br>flash_stage3d_baseline: enabled<br>gpu_compositing: enabled<br>multiple_raster_threads: enabled_on<br>oop_rasterization: disabled_off<br>protected_video_decode: unavailable_off<br>rasterization: enabled<br>skia_renderer: disabled_off_ok<br>video_decode: enabled<br>viz_display_compositor: enabled_on<br>viz_hit_test_surface_layer: disabled_off_ok<br>webgl: enabled<br>webgl2: enabled
Load (avg) undefined
Memory (System) 7.90GB (1.68GB free)
Process Argv
Screen Reader no
VM 0%

</details><details><summary>Extensions (7)</summary>

Extension Author (truncated) Version
html-snippets abu 0.2.1
vscode-eslint dba 2.1.5
vscode-npm-script eg2 0.3.12
output-colorizer IBM 0.1.2
luacoderassist liw 2.3.9
vscode-language-pack-zh-hans MS- 1.46.3
vetur oct 0.24.0

</details> <!-- generated by issue reporter -->

closed time in 9 days

AnnAngela

delete branch andrewbranch/TypeScript

delete branch : bug/37859

delete time in 9 days

push eventmicrosoft/TypeScript

Andrew Branch

commit sha 58ed610ef19f6fbbb100cec60c506752c6ca149a

Allow distinct string enum members with identical property names to form unions in mapped types (#39101)

view details

push time in 9 days

PR merged microsoft/TypeScript

Reviewers
Allow distinct string enum members with identical property names to form unions in mapped types Author: Team

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #37859

See bug for discussion.

+308 -16

1 comment

5 changed files

andrewbranch

pr closed time in 9 days

issue closedmicrosoft/TypeScript

Map derived from discriminated union has wrong type when discriminator property has the same value

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

TypeScript Version: 3.8.3

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms:

  • map from discriminated union same key
  • discriminated union same key

Expected behavior:

CatMap should have type

type CatMap = {
    cat: TerrestrialCat[] | AlienCat[];
}

Actual behavior:

CatMap has type

type CatMap = {
    cat: AlienCat[];
}

<!-- Did you find other bugs that looked similar? --> Related Issues:

Code

enum TerrestrialAnimalTypes {
    CAT = "cat",
};

enum AlienAnimalTypes {
    CAT = "cat",
};

type AnimalTypes = TerrestrialAnimalTypes | AlienAnimalTypes;

interface TerrestrialCat {
    type: TerrestrialAnimalTypes.CAT;
    address: string;
}

interface AlienCat {
    type: AlienAnimalTypes.CAT
    planet: string;
}

type Cats = TerrestrialCat | AlienCat;

// type A = TerrestrialCat | AlienCat
type A = Extract<Cats, { type: "cat" }>;

/*
 * type CatMap = {
 *   cat: AlienCat[];
 * }
 */
type CatMap = {
    [V in AnimalTypes]: Extract<Cats, { type: V }>[]
};

<details><summary><b>Output</b></summary>

"use strict";
var AnimalTypes;
(function (AnimalTypes) {
    AnimalTypes["CAT"] = "cat";
})(AnimalTypes || (AnimalTypes = {}));
;

</details>

<details><summary><b>Compiler Options</b></summary>

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

</details>

Playground Link: Provided

closed time in 9 days

chenlijun99

Pull request review commentDefinitelyTyped/DefinitelyTyped

typings for @rdfjs/term-map

+// Type definitions for @rdfjs/term-map 1.0+// Project: https://github.com/rdfjs-base/term-map+// Definitions by: tpluscode <https://github.com/tpluscode>+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped++import { Term } from "rdf-js";++declare namespace TermMap {

There’s no reason to distinguish between the interface and the class—that’s the whole point of declaration merging.

tpluscode

comment created time in 9 days

issue closedmicrosoft/TypeScript

Diagnostics still include absolute module paths on macOS

Seems to be a regression of the fix for #25747, or it was never working as intended on some platforms.

According to #25747, error messages should be showing relative paths to referenced modules. Instead I'm seeing a chain of ../s to get back to the root path, followed by the full absolute path. This is worse that if it just showed the absolute path. The screenshot below shows a simple workspace with no tsconfig, but I'm seeing this in every workspace, even with tsconfig.json present.

image

Expected behavior:

Module '"./bar"' has no exported member 'bar'.

Actual behavior:

Module '"../../../Users/rhudson/wtf-ts/bar"' has no exported member 'bar'.

typescript 3.8.3

VSCode info:

Version: 1.44.1 Commit: a9f8623ec050e5f0b44cc8ce8204a1455884749f Date: 2020-04-11T01:47:00.296Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Darwin x64 18.7.0

closed time in 12 days

dinofx

issue commentmicrosoft/TypeScript

Diagnostics still include absolute module paths on macOS

This is fixed in TypeScript 3.9.

dinofx

comment created time in 12 days

push eventmicrosoft/TypeScript

Andrew Branch

commit sha 3d22a4fd72625a03feb6f020dae3f7a8c4b5929c

Preserve newlines between try/catch/finally, if/else, do/while (#39280) * Preserve newlines between try/catch, if/else, do/while * Update baselines

view details

push time in 12 days

issue closedmicrosoft/TypeScript

Refactor changes if/else formatting

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

<!-- Please try to reproduce the issue with the latest published version. It may have already been fixed. For npm: typescript@next This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly --> TypeScript Version: 3.9.0-dev.20200416

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms:

  • refactor / refactoring
  • format

Code For the code:

function foo() {
    if (true) {
        console.log(1);
    } else {
        console.log(1);
    }
}
  1. Select the body of the function and run extract to function

Bug: In the new function, a new line is added before the else:

function foo() {
    newFunction();
}

function newFunction() {
    if (true) {
        console.log(1);
    }
    else {
        console.log(1);
    }
}

closed time in 12 days

mjbvz

PR merged microsoft/TypeScript

Reviewers
Preserve newlines between try/catch/finally, if/else, do/while Author: Team

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [ ] Code is up-to-date with the master branch
  • [ ] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #38017

+124 -109

0 comment

50 changed files

andrewbranch

pr closed time in 12 days

pull request commentmicrosoft/TypeScript

Don’t auto-import paths that are in a referenced project’s outDir

That depends on the relationship between the outDir of the importing file and the outDir of the imported file. Consider this non-monorepo project references scenario:

src/
  a/
    tsconfig.json - outDir: ../../out/a
    index.ts
  b/
    tsconfig.json - outDir: ../../out/b
    index.ts

out/
  a/
    index.js
    index.d.ts
  b/
    index.js
    index.d.ts

Because the outDirs of the two projects have the same relationship as the rootDirs, it’s safe and conventional to write imports from a to b as import { B } from "../b";. But as of #37482, you get two suggestions:

image

I can’t see any reason why you would ever want the latter. It’s not wrong on disk now, but what happens if you use out as the context for a Docker build, copying files to a container image? That image will be broken unless the working directory on the container is also named out. These module specifiers aren’t portable.

andrewbranch

comment created time in 12 days

more