import React from 'react';
import logo from './logo.svg';
import './App.css';
import MonacoEditor from 'react-monaco-editor';
import { useRef, useState,useEffect } from 'react';
function App() {
const editorRef = useRef(null);
const monacoRef = useRef(null);
const decorationsRef = useRef([]);
const handleEditorDidMount = (editor: any, monaco: any) => {
editorRef.current = editor;
monacoRef.current = monaco;
// Add an event listener for cursor position changes
editor.onDidChangeCursorSelection(() => {
const selection = editor.getSelection();
// if (selection.isEmpty()) {
// // Remove decorations if selection is empty
// editor.deltaDecorations(decorationsRef.current, []);
// return;
// }
const lineNumber = selection.positionLineNumber;
const lineContent = editor.getModel().getLineContent(lineNumber);
if (lineContent !== "") {
// Add decoration if the line starts with 'var'
const newDecorations = editor.deltaDecorations(decorationsRef.current, [
{
range: new monaco.Range(lineNumber, 1, lineNumber, 1),
options: {
isWholeLine: true,
afterContentClassName: 'myAfterContentDecoration'
}
}
]);
decorationsRef.current = newDecorations;
} else {
// Remove decorations if the line does not start with 'var'
editor.deltaDecorations(decorationsRef.current, []);
}
});
};
useEffect(() => {
// Define custom styles for the decorations
const style = document.createElement('style');
style.innerHTML = `
.myAfterContentDecoration::after {
content: ' // 备注';
color: green;
font-weight: bold;
}
`;
document.head.appendChild(style);
}, []);
const clickButton = () => {
if(monacoRef.current) { // null
console.log(monacoRef.current) // never
}
}
return (
<div style={{'margin':'100px auto', 'width': '800px'}}>
<MonacoEditor
value={"112233"}
editorDidMount={handleEditorDidMount}
/>
<button onClick={clickButton}>点击</button>
</div>
);
}
export default App;
在代码:clickButton
里面, if(monacoRef.current)
这里是null
,但是在console.log(monacoRef.current)
里面是never
:
因为是never
, 就不能点进行使用属性了。
请问这个问题应该如何处理呢?
向 useRef 添加泛型参数:
import { useRef } from 'react'
const a = useRef(null), b = useRef<number>(null)
function onClick() {
if (a.current) {
console.log(a.current) // never
}
if (b.current) {
console.log(b.current) // number
}
}
const monacoRef = useRef<XXX>(null);
在 XXX 的位置补上泛型。
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
const monacoRef = useRef<typeof monaco | null>(null);
https://github.com/react-monaco-editor/react-monaco-editor/blob/master/src/editor.tsx#L25
在你的 TypeScript 代码中,出现 never
类型的问题通常是因为 TypeScript 的类型推断系统在某些条件下无法确定一个变量确切的类型,从而将其推断为 never
。然而,在你的特定例子中,monacoRef.current
被声明为 any
类型的引用(由于 useRef
的泛型参数未指定),并且你提到在 clickButton
函数中 monacoRef.current
被认为是 null
,但在 console.log
时显示为 never
。这实际上是一个误解或配置问题,因为 TypeScript 通常不会将 null
推断为 never
。
不过,你的代码中存在一个潜在的问题,即 monacoRef.current
可能在编辑器未完全挂载前就被访问(即 monacoRef.current
仍然是 null
)。为了避免这个问题,你可以通过检查 monacoRef.current
是否为 null
或 undefined
来确保它已被正确设置:
const clickButton = () => {
if (monacoRef.current !== null && monacoRef.current !== undefined) {
console.log(monacoRef.current); // 现在 monacoRef.current 不会是 never 类型
} else {
console.log('Monaco editor has not mounted yet.');
}
};
此外,虽然 useRef
的泛型参数在这里被省略了,但最好明确指定它,以提供更好的类型安全性和更清晰的代码意图。由于你正在存储 monaco
实例,你可以尝试如下方式声明 monacoRef
:
const monacoRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
这样,TypeScript 就能更准确地推断 monacoRef.current
的类型,并在你尝试访问其属性或方法时提供编译时检查。
最后,关于你提到的 never
类型,这通常不是由简单的 null
检查引起的。如果你在某个地方看到了 never
类型,并且它导致了编译错误,那么很可能是你的类型逻辑在某个分支中导致了矛盾,使得 TypeScript 推断出没有任何可能的值能满足该类型(即 never
)。然而,在你的这个例子中,问题更可能是由于误解了 TypeScript 的行为或错误地使用了 console.log
的结果解读。
我尝试使用 typescript创建一个 forwardRef + useImperativeHandle的demo示例: demo如下: 但是见报错结果: 请问这个应该如何做才能避免呢?
本节介绍 never 和 unknown 类型,其中 unknown 类型作为 any 类型对应的安全类型使用起来更加安全,如果有 any 类型的使用需求,应尽量使用 unknown 类型来替代 any 类型。 1. 慕课解释 never 类型表示那些永不存在的值的类型。 unknown 类型是 any 类型对应的安全类型。 2. never 类型 never 类型是任何类型的子类型,也可以赋值给
由于项目功能越来越多,单个 vue 文件代码量过于臃肿,因此产生了将代码分离的想法并在昨天手写了个 npm script 用来生成组件套件。 生成的代码文件如果不使用 TS 是没有任何报错信息的,反之则会在模板文件出现类型推导错误的情况,生成的代码如下: 在生成的 .vue 文件中,如果不加入 // @ts-ignore 会出现错误提示 没有与此调用匹配的重载;而加上后,不管在 TS 文件如何定义
never 创建一个永远不会发出元素的 Observable never 操作符将创建一个 Observable,这个 Observable 不会产生任何事件。 演示 创建一个不会产生任何事件的 Observable: let id = Observable<Int>.never() 它相当于: let id = Observable<Int>.create { observer in
在编写代码时候发现 toRef 无法传入第二个参数,因为 key 类型被指定成了 never。 我在vue官网上没发现有这个定义。。不太确定哪里出现了问题。
这里的 create 方法参数的类型理想状态下应该是 ParamsA | ParamsB,这里为什么会是 ParamsA & ParamsB 在线查看代码