From 5cf6bcdc749c3c94fb9d2de76074cc392bd3dc78 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 4 Apr 2023 23:14:50 +0200 Subject: [PATCH 1/7] chore(website): [playground] add types tab to playground --- .../website/src/components/Playground.tsx | 42 +++--- packages/website/src/components/config.ts | 1 + .../src/components/editor/LoadedEditor.tsx | 20 ++- .../website/src/components/editor/types.ts | 8 +- .../src/components/hooks/useHashState.ts | 1 + .../src/components/linter/WebLinter.ts | 9 +- .../website/src/components/linter/types.ts | 10 ++ .../typeDetails/SimplifiedTreeView.tsx | 77 ++++++++++ .../src/components/typeDetails/TypeInfo.tsx | 139 ++++++++++++++++++ .../components/typeDetails/TypesDetails.tsx | 66 +++++++++ packages/website/src/components/types.ts | 2 +- 11 files changed, 334 insertions(+), 41 deletions(-) create mode 100644 packages/website/src/components/linter/types.ts create mode 100644 packages/website/src/components/typeDetails/SimplifiedTreeView.tsx create mode 100644 packages/website/src/components/typeDetails/TypeInfo.tsx create mode 100644 packages/website/src/components/typeDetails/TypesDetails.tsx diff --git a/packages/website/src/components/Playground.tsx b/packages/website/src/components/Playground.tsx index 591bc5c9bf00..7ce2d9b29b07 100644 --- a/packages/website/src/components/Playground.tsx +++ b/packages/website/src/components/Playground.tsx @@ -1,8 +1,6 @@ -import type { TSESTree } from '@typescript-eslint/utils'; import clsx from 'clsx'; import type * as ESQuery from 'esquery'; import React, { useCallback, useState } from 'react'; -import type { SourceFile } from 'typescript'; import ASTViewer from './ast/ASTViewer'; import { detailTabs } from './config'; @@ -16,9 +14,11 @@ import { ESQueryFilter } from './ESQueryFilter'; import useHashState from './hooks/useHashState'; import EditorTabs from './layout/EditorTabs'; import Loader from './layout/Loader'; +import type { ASTModel } from './linter/types'; import OptionsSelector from './OptionsSelector'; import styles from './Playground.module.css'; import ConditionalSplitPane from './SplitPane/ConditionalSplitPane'; +import { TypesDetails } from './typeDetails/TypesDetails'; import type { ErrorGroup, RuleDetails, SelectedRange, TabType } from './types'; function Playground(): JSX.Element { @@ -31,9 +31,7 @@ function Playground(): JSX.Element { tsconfig: defaultTsConfig, eslintrc: defaultEslintConfig, }); - const [esAst, setEsAst] = useState(); - const [tsAst, setTsAST] = useState(); - const [scope, setScope] = useState | null>(); + const [astModel, setAstModel] = useState(); const [markers, setMarkers] = useState(); const [ruleNames, setRuleNames] = useState([]); const [isLoading, setIsLoading] = useState(true); @@ -71,15 +69,6 @@ function Playground(): JSX.Element { } }, []); - const astToShow = - state.showAST === 'ts' - ? tsAst - : state.showAST === 'scope' - ? scope - : state.showAST === 'es' - ? esAst - : undefined; - return (
@@ -147,9 +136,7 @@ function Playground(): JSX.Element { eslintrc={state.eslintrc} sourceType={state.sourceType} showAST={state.showAST} - onEsASTChange={setEsAst} - onTsASTChange={setTsAST} - onScopeChange={setScope} + onASTChange={setAstModel} onMarkersChange={setMarkers} selectedRange={selectedRange} onChange={setState} @@ -171,7 +158,6 @@ function Playground(): JSX.Element { /> )}
- {(state.showAST === 'es' && esQueryError && ( )) || - (state.showAST && astToShow && ( + (state.showAST === 'types' && astModel?.storedTsAST && ( + + )) || + (state.showAST && astModel && ( = ({ eslintrc, selectedRange, fileType, - onEsASTChange, - onScopeChange, - onTsASTChange, + onASTChange, onMarkersChange, onChange, onSelect, @@ -146,9 +144,12 @@ export const LoadedEditor: React.FC = ({ onMarkersChange(e as Error); } - onEsASTChange(webLinter.storedAST); - onTsASTChange(webLinter.storedTsAST); - onScopeChange(webLinter.storedScope); + onASTChange({ + storedAST: webLinter.storedAST, + storedTsAST: webLinter.storedTsAST, + storedScope: webLinter.storedScope, + typeChecker: webLinter.typeChecker, + }); const position = sandboxInstance.editor.getPosition(); onSelect(position ? tabs.code.getOffsetAt(position) : undefined); @@ -162,9 +163,7 @@ export const LoadedEditor: React.FC = ({ eslintrc, sourceType, webLinter, - onEsASTChange, - onTsASTChange, - onScopeChange, + onASTChange, onSelect, sandboxInstance.editor, sandboxInstance.monaco.editor, @@ -284,8 +283,7 @@ export const LoadedEditor: React.FC = ({ onChange, onSelect, sandboxInstance.editor, - sandboxInstance.monaco.editor, - sandboxInstance.monaco.languages.json.jsonDefaults, + sandboxInstance.monaco, tabs.code, tabs.eslintrc, tabs.tsconfig, diff --git a/packages/website/src/components/editor/types.ts b/packages/website/src/components/editor/types.ts index e6bc986428fc..eef78ae4da77 100644 --- a/packages/website/src/components/editor/types.ts +++ b/packages/website/src/components/editor/types.ts @@ -1,15 +1,11 @@ -import type { TSESTree } from '@typescript-eslint/utils'; -import type { SourceFile } from 'typescript'; - +import type { ASTModel } from '../linter/types'; import type { ConfigModel, ErrorGroup, SelectedRange, TabType } from '../types'; export interface CommonEditorProps extends ConfigModel { readonly activeTab: TabType; readonly selectedRange?: SelectedRange; readonly onChange: (cfg: Partial) => void; - readonly onTsASTChange: (value: undefined | SourceFile) => void; - readonly onEsASTChange: (value: undefined | TSESTree.Program) => void; - readonly onScopeChange: (value: undefined | Record) => void; + readonly onASTChange: (value: undefined | ASTModel) => void; readonly onMarkersChange: (value: ErrorGroup[] | Error) => void; readonly onSelect: (position?: number) => void; } diff --git a/packages/website/src/components/hooks/useHashState.ts b/packages/website/src/components/hooks/useHashState.ts index de2f475154b3..347048c95fe9 100644 --- a/packages/website/src/components/hooks/useHashState.ts +++ b/packages/website/src/components/hooks/useHashState.ts @@ -21,6 +21,7 @@ function readShowAST(value: string | null): ConfigShowAst { case 'es': case 'ts': case 'scope': + case 'types': return value; } return value ? 'es' : false; diff --git a/packages/website/src/components/linter/WebLinter.ts b/packages/website/src/components/linter/WebLinter.ts index f789a7417173..7a690fe44241 100644 --- a/packages/website/src/components/linter/WebLinter.ts +++ b/packages/website/src/components/linter/WebLinter.ts @@ -1,4 +1,4 @@ -import type { analyze } from '@typescript-eslint/scope-manager'; +import type { analyze, ScopeManager } from '@typescript-eslint/scope-manager'; import type { ParserOptions } from '@typescript-eslint/types'; import type { astConverter, @@ -27,7 +27,8 @@ export class WebLinter { public storedAST?: TSESTree.Program; public storedTsAST?: ts.SourceFile; - public storedScope?: Record; + public storedScope?: ScopeManager; + public typeChecker?: ts.TypeChecker; private compilerOptions: ts.CompilerOptions; private eslintConfig = eslintConfig; @@ -102,6 +103,7 @@ export class WebLinter { this.storedAST = undefined; this.storedTsAST = undefined; this.storedScope = undefined; + this.typeChecker = undefined; this.host.writeFile(fileName, code || '\n', false); @@ -126,7 +128,8 @@ export class WebLinter { this.storedAST = ast; this.storedTsAST = tsAst; - this.storedScope = scopeManager as unknown as Record; + this.storedScope = scopeManager; + this.typeChecker = checker; return { ast, diff --git a/packages/website/src/components/linter/types.ts b/packages/website/src/components/linter/types.ts new file mode 100644 index 000000000000..54bf25c05646 --- /dev/null +++ b/packages/website/src/components/linter/types.ts @@ -0,0 +1,10 @@ +import type { ScopeManager } from '@typescript-eslint/scope-manager'; +import type { TSESTree } from '@typescript-eslint/utils'; +import type * as ts from 'typescript'; + +export interface ASTModel { + storedAST?: TSESTree.Program; + storedTsAST?: ts.Node; + storedScope?: ScopeManager; + typeChecker?: ts.TypeChecker; +} diff --git a/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx new file mode 100644 index 000000000000..d4925665abfc --- /dev/null +++ b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx @@ -0,0 +1,77 @@ +import clsx from 'clsx'; +import React, { useCallback, useMemo } from 'react'; +import type * as ts from 'typescript'; + +import styles from '../ast/ASTViewer.module.css'; +import PropertyName from '../ast/PropertyName'; +import { tsEnumToString } from '../ast/tsUtils'; +import type { OnHoverNodeFn } from '../ast/types'; +import { getRange, isTSNode } from '../ast/utils'; + +export interface SimplifiedTreeViewProps { + readonly value: ts.Node; + readonly selectedNode: ts.Node | undefined; + readonly onSelect: (value: ts.Node) => void; + readonly onHoverNode?: OnHoverNodeFn; +} + +function SimplifiedItem({ + value, + onSelect, + selectedNode, + onHoverNode, +}: SimplifiedTreeViewProps): JSX.Element { + const items = useMemo(() => { + const result: ts.Node[] = []; + value.forEachChild(child => { + result.push(child); + }); + return result; + }, [value]); + + const onHover = useCallback( + (v: boolean) => { + if (isTSNode(value) && onHoverNode) { + return onHoverNode(v ? getRange(value, 'tsNode') : undefined); + } + }, + [onHoverNode, value], + ); + + return ( +
+ + { + onSelect(value); + }} + /> + + +
+ {items.map((item, index) => ( + + ))} +
+
+ ); +} + +export function SimplifiedTreeView( + params: SimplifiedTreeViewProps, +): JSX.Element { + return ( +
+ +
+ ); +} diff --git a/packages/website/src/components/typeDetails/TypeInfo.tsx b/packages/website/src/components/typeDetails/TypeInfo.tsx new file mode 100644 index 000000000000..231ba4e3347d --- /dev/null +++ b/packages/website/src/components/typeDetails/TypeInfo.tsx @@ -0,0 +1,139 @@ +import React, { useMemo } from 'react'; +import type * as ts from 'typescript'; + +import ASTViewer from '../ast/ASTViewer'; +import astStyles from '../ast/ASTViewer.module.css'; +import type { OnHoverNodeFn } from '../ast/types'; + +export interface TypeInfoProps { + readonly value: ts.Node; + readonly typeChecker?: ts.TypeChecker; + readonly onHoverNode?: OnHoverNodeFn; +} + +interface InfoModel { + type?: unknown; + typeString?: string; + contextualType?: unknown; + contextualTypeString?: string; + symbol?: unknown; + signature?: unknown; + flowNode?: unknown; +} + +interface SimpleFieldProps { + readonly value: string | undefined; + readonly label: string; +} + +interface TypeGroupProps { + readonly label: string; + readonly type?: unknown; + readonly string?: string; + readonly onHoverNode?: OnHoverNodeFn; +} + +function SimpleField(props: SimpleFieldProps): JSX.Element { + return ( +
+ {props.label} + : + {String(props.value)} +
+ ); +} + +function TypeGroup(props: TypeGroupProps): JSX.Element { + return ( + <> +

{props.label}

+ {(props.type && ( + <> + {props.string && ( + + )} + + + )) ||
None
} + + ); +} + +export function TypeInfo({ + value, + typeChecker, + onHoverNode, +}: TypeInfoProps): JSX.Element { + const computed = useMemo(() => { + if (!typeChecker || !value) { + return undefined; + } + const info: InfoModel = {}; + try { + const type = typeChecker.getTypeAtLocation(value); + info.type = type; + info.typeString = typeChecker.typeToString(type); + info.symbol = type.getSymbol(); + let signature = type.getCallSignatures(); + if (signature.length === 0) { + signature = type.getConstructSignatures(); + } + info.signature = signature.length > 0 ? signature : undefined; + // @ts-expect-error not part of public api + info.flowNode = value.flowNode ?? value.endFlowNode ?? undefined; + } catch (e: unknown) { + info.type = e; + } + try { + // @ts-expect-error just fail if node type is not correct + const contextualType = typeChecker.getContextualType(value); + info.contextualType = contextualType; + if (contextualType) { + info.contextualTypeString = typeChecker.typeToString(contextualType); + } + } catch (_e: unknown) { + info.contextualType = undefined; + } + return info; + }, [value, typeChecker]); + + if (!typeChecker || !computed) { + return
TypeChecker not available
; + } + + return ( +
+ <> +

Node

+ + + + + + + +
+ ); +} diff --git a/packages/website/src/components/typeDetails/TypesDetails.tsx b/packages/website/src/components/typeDetails/TypesDetails.tsx new file mode 100644 index 000000000000..3bd24fe30ffe --- /dev/null +++ b/packages/website/src/components/typeDetails/TypesDetails.tsx @@ -0,0 +1,66 @@ +import React, { useEffect, useState } from 'react'; +import type * as ts from 'typescript'; + +import { findSelectionPath } from '../ast/selectedRange'; +import type { OnHoverNodeFn } from '../ast/types'; +import { isTSNode } from '../ast/utils'; +import styles from '../Playground.module.css'; +import ConditionalSplitPane from '../SplitPane/ConditionalSplitPane'; +import { SimplifiedTreeView } from './SimplifiedTreeView'; +import { TypeInfo } from './TypeInfo'; + +export interface TypesDetailsProps { + readonly value: ts.Node; + readonly typeChecker?: ts.TypeChecker; + readonly cursorPosition?: number; + readonly onHoverNode?: OnHoverNodeFn; +} + +export function TypesDetails({ + cursorPosition, + value, + typeChecker, + onHoverNode, +}: TypesDetailsProps): JSX.Element { + const [selectedNode, setSelectedNode] = useState(value); + + useEffect(() => { + if (cursorPosition) { + const item = findSelectionPath(value, cursorPosition); + if (item.node && isTSNode(item.node)) { + setSelectedNode(item.node); + } + } + }, [cursorPosition, value]); + + return ( + +
+
+ +
+
+ {selectedNode && ( +
+
+ +
+
+ )} +
+ ); +} diff --git a/packages/website/src/components/types.ts b/packages/website/src/components/types.ts index 8a128da07b14..d8039a1c27de 100644 --- a/packages/website/src/components/types.ts +++ b/packages/website/src/components/types.ts @@ -18,7 +18,7 @@ export type TabType = 'code' | 'tsconfig' | 'eslintrc'; export type ConfigFileType = `${ts.Extension}`; -export type ConfigShowAst = false | 'es' | 'ts' | 'scope'; +export type ConfigShowAst = false | 'es' | 'ts' | 'scope' | 'types'; export interface ConfigModel { fileType?: ConfigFileType; From 5a74892ecb5ebf541b2a823911d88b184cbc9b39 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 4 Apr 2023 23:18:38 +0200 Subject: [PATCH 2/7] chore(website): [playground] add missing styles --- .../src/components/Playground.module.css | 11 ++++++++ .../components/typeDetails/TypesDetails.tsx | 28 ++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/packages/website/src/components/Playground.module.css b/packages/website/src/components/Playground.module.css index 0ce6400ded7d..4f607f7577f4 100644 --- a/packages/website/src/components/Playground.module.css +++ b/packages/website/src/components/Playground.module.css @@ -22,6 +22,17 @@ width: calc(100vw - 20rem); } +.playgroundInfoContainer { + display: flex; + flex-direction: column; + flex: 1 1 0; + height: 100%; + background: var(--code-editor-bg); + border: 1px solid var(--playground-secondary-color); + border-left: none; + overflow: auto; +} + .astViewer { height: 100%; width: 100%; diff --git a/packages/website/src/components/typeDetails/TypesDetails.tsx b/packages/website/src/components/typeDetails/TypesDetails.tsx index 3bd24fe30ffe..32e5c4b74ff9 100644 --- a/packages/website/src/components/typeDetails/TypesDetails.tsx +++ b/packages/website/src/components/typeDetails/TypesDetails.tsx @@ -40,26 +40,22 @@ export function TypesDetails({ defaultSize="50%" pane2Style={{ overflow: 'hidden' }} > -
+
+ +
+ {selectedNode && (
-
-
- {selectedNode && ( -
-
- -
-
)} ); From 14e432377227764e24d77d235f8cb1158ff8d4b8 Mon Sep 17 00:00:00 2001 From: Armano Date: Fri, 7 Apr 2023 11:49:32 +0200 Subject: [PATCH 3/7] fix: remove unnecessary code after merge --- packages/website/src/components/editor/LoadedEditor.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/website/src/components/editor/LoadedEditor.tsx b/packages/website/src/components/editor/LoadedEditor.tsx index b512e46ebfff..a08759fcceb7 100644 --- a/packages/website/src/components/editor/LoadedEditor.tsx +++ b/packages/website/src/components/editor/LoadedEditor.tsx @@ -137,12 +137,7 @@ export const LoadedEditor: React.FC = ({ useEffect(() => { const disposable = webLinter.onParse((uri, model) => { - onASTChange({ - storedAST: model.storedAST, - storedTsAST: model.storedTsAST, - storedScope: model.storedScope, - typeChecker: model.typeChecker, - }); + onASTChange(model); }); return () => disposable(); }, [webLinter, onASTChange]); From af69a7e426a9983b86b4e3c2136388ab9389eb06 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 15 Aug 2023 11:28:14 +0200 Subject: [PATCH 4/7] fix: correct package file --- packages/website-eslint/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 1e14a9e5a74d..156f2db040a9 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -31,9 +31,7 @@ "@typescript-eslint/eslint-plugin": "6.4.0", "@typescript-eslint/parser": "6.4.0", "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.0.0", "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/utils": "6.0.0", "@typescript-eslint/visitor-keys": "6.4.0", "esbuild": "~0.19.0", "eslint": "*", From ed72ba35f2a7db4c765229c6f6c09ba3c614c577 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 15 Aug 2023 11:40:48 +0200 Subject: [PATCH 5/7] fix: apply changes after merge --- .../src/components/Playground.module.css | 18 ++++++------------ .../typeDetails/SimplifiedTreeView.tsx | 4 ++-- .../src/components/typeDetails/TypeInfo.tsx | 14 ++++++++------ .../components/typeDetails/TypesDetails.tsx | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/packages/website/src/components/Playground.module.css b/packages/website/src/components/Playground.module.css index 746e3fdb5cf1..7e2a6b4d330e 100644 --- a/packages/website/src/components/Playground.module.css +++ b/packages/website/src/components/Playground.module.css @@ -22,17 +22,6 @@ width: calc(100vw - 20rem); } -.playgroundInfoContainer { - display: flex; - flex-direction: column; - flex: 1 1 0; - height: 100%; - background: var(--code-editor-bg); - border: 1px solid var(--playground-secondary-color); - border-left: none; - overflow: auto; -} - .astViewer { height: 100%; width: 100%; @@ -61,10 +50,15 @@ z-index: 1; } -.tabCode { +.tabCode, +.playgroundInfoContainer { height: calc(100% - 41px); } +.playgroundInfoContainer { + overflow: auto; +} + .hidden { display: none; visibility: hidden; diff --git a/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx index d4925665abfc..c5dc1b37926d 100644 --- a/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx +++ b/packages/website/src/components/typeDetails/SimplifiedTreeView.tsx @@ -20,7 +20,7 @@ function SimplifiedItem({ onSelect, selectedNode, onHoverNode, -}: SimplifiedTreeViewProps): JSX.Element { +}: SimplifiedTreeViewProps): React.JSX.Element { const items = useMemo(() => { const result: ts.Node[] = []; value.forEachChild(child => { @@ -68,7 +68,7 @@ function SimplifiedItem({ export function SimplifiedTreeView( params: SimplifiedTreeViewProps, -): JSX.Element { +): React.JSX.Element { return (
diff --git a/packages/website/src/components/typeDetails/TypeInfo.tsx b/packages/website/src/components/typeDetails/TypeInfo.tsx index 231ba4e3347d..71a60f31e128 100644 --- a/packages/website/src/components/typeDetails/TypeInfo.tsx +++ b/packages/website/src/components/typeDetails/TypeInfo.tsx @@ -33,7 +33,7 @@ interface TypeGroupProps { readonly onHoverNode?: OnHoverNodeFn; } -function SimpleField(props: SimpleFieldProps): JSX.Element { +function SimpleField(props: SimpleFieldProps): React.JSX.Element { return (
{props.label} @@ -43,18 +43,20 @@ function SimpleField(props: SimpleFieldProps): JSX.Element { ); } -function TypeGroup(props: TypeGroupProps): JSX.Element { +function TypeGroup(props: TypeGroupProps): React.JSX.Element { return ( <>

{props.label}

- {(props.type && ( + {props.type ? ( <> {props.string && ( )} - )) ||
None
} + ) : ( +
None
+ )} ); } @@ -63,7 +65,7 @@ export function TypeInfo({ value, typeChecker, onHoverNode, -}: TypeInfoProps): JSX.Element { +}: TypeInfoProps): React.JSX.Element { const computed = useMemo(() => { if (!typeChecker || !value) { return undefined; @@ -85,7 +87,7 @@ export function TypeInfo({ info.type = e; } try { - // @ts-expect-error just fail if node type is not correct + // @ts-expect-error just fail if a node type is not correct const contextualType = typeChecker.getContextualType(value); info.contextualType = contextualType; if (contextualType) { diff --git a/packages/website/src/components/typeDetails/TypesDetails.tsx b/packages/website/src/components/typeDetails/TypesDetails.tsx index 32e5c4b74ff9..3059567872de 100644 --- a/packages/website/src/components/typeDetails/TypesDetails.tsx +++ b/packages/website/src/components/typeDetails/TypesDetails.tsx @@ -21,7 +21,7 @@ export function TypesDetails({ value, typeChecker, onHoverNode, -}: TypesDetailsProps): JSX.Element { +}: TypesDetailsProps): React.JSX.Element { const [selectedNode, setSelectedNode] = useState(value); useEffect(() => { From f1c0cdbf2f8c45c28f407ace0fffe9684e79b031 Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 21 Aug 2023 19:19:53 +0200 Subject: [PATCH 6/7] fix: unify playgroundInfoContainer with tabCode --- packages/website/src/components/Playground.module.css | 6 +----- .../website/src/components/typeDetails/TypesDetails.tsx | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/website/src/components/Playground.module.css b/packages/website/src/components/Playground.module.css index 7e2a6b4d330e..b824d441fafc 100644 --- a/packages/website/src/components/Playground.module.css +++ b/packages/website/src/components/Playground.module.css @@ -50,12 +50,8 @@ z-index: 1; } -.tabCode, -.playgroundInfoContainer { +.tabCode { height: calc(100% - 41px); -} - -.playgroundInfoContainer { overflow: auto; } diff --git a/packages/website/src/components/typeDetails/TypesDetails.tsx b/packages/website/src/components/typeDetails/TypesDetails.tsx index 3059567872de..28dd2f824deb 100644 --- a/packages/website/src/components/typeDetails/TypesDetails.tsx +++ b/packages/website/src/components/typeDetails/TypesDetails.tsx @@ -40,7 +40,7 @@ export function TypesDetails({ defaultSize="50%" pane2Style={{ overflow: 'hidden' }} > -
+
{selectedNode && ( -
+
Date: Mon, 21 Aug 2023 19:20:48 +0200 Subject: [PATCH 7/7] Update packages/website/src/components/typeDetails/TypeInfo.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Josh Goldberg ✨ --- packages/website/src/components/typeDetails/TypeInfo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/src/components/typeDetails/TypeInfo.tsx b/packages/website/src/components/typeDetails/TypeInfo.tsx index 71a60f31e128..87084650d124 100644 --- a/packages/website/src/components/typeDetails/TypeInfo.tsx +++ b/packages/website/src/components/typeDetails/TypeInfo.tsx @@ -93,7 +93,7 @@ export function TypeInfo({ if (contextualType) { info.contextualTypeString = typeChecker.typeToString(contextualType); } - } catch (_e: unknown) { + } catch { info.contextualType = undefined; } return info; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy