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;