gra*_*nal 166 typescript
我有一个类型:
type tSelectProtected = {
handleSelector?: string,
data?: tSelectDataItem[],
wrapperEle?: HTMLElement,
inputEle?: HTMLElement,
listEle?: HTMLElement,
resultEle?: HTMLElement,
maxVisibleListItems?: number
}
Run Code Online (Sandbox Code Playgroud)
我宣布一个全局模块明智的变量:
var $protected : tSelectProtected = {};
Run Code Online (Sandbox Code Playgroud)
我在function1范围内分配了适当的值:
$protected.listEle = document.createElement('DIV');
Run Code Online (Sandbox Code Playgroud)
我稍后在function2范围内调用:
$protected.listEle.classList.add('visible');
Run Code Online (Sandbox Code Playgroud)
我收到TypeScript错误:
error TS2533: Object is possibly 'null' or 'undefined'
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用显式检查type来平息编译器,但对于大多数非平凡的情况,这似乎是非常不方便的.
如何在不禁用TS编译器检查的情况下处理这种情况?
Rya*_*ugh 494
如果从外部知道表达式不是null或者undefined,则可以使用非null断言运算符!来强制转换这些类型:
// Error, some.expr may be null or undefined
let x = some.expr.thing;
// OK
let y = some.expr!.thing;
Run Code Online (Sandbox Code Playgroud)
Dou*_*las 75
此功能称为"严格空检查",将其关闭以确保--strictNullChecks未设置编译器标志.
然而,存在null已经被描述为十亿美元的错误,所以这是令人兴奋地看到语言如打字稿引入一个修复.我强烈建议保持打开状态.
解决此问题的一种方法是确保值永远不会,null或者undefined例如通过预先初始化它们:
interface SelectProtected {
readonly wrapperElement: HTMLDivElement;
readonly inputElement: HTMLInputElement;
}
const selectProtected: SelectProtected = {
wrapperElement: document.createElement("div"),
inputElement: document.createElement("input")
};
Run Code Online (Sandbox Code Playgroud)
Van*_*esh 51
如果需要,您可以通过添加评论来抑制(注意以下)
// @ts-ignore: Object is possibly 'null'.
不是对 OP 问题的直接回答,而是在我的带有 Typescript 的 React 应用程序中 - v3.6.2
tslint -v5.20.0
并使用以下代码
const refToElement = useRef(null);
if (refToElement && refToElement.current) {
refToElement.current.focus(); // Object is possibly 'null' (for refToElement.current)
}
Run Code Online (Sandbox Code Playgroud)
我通过抑制该行的编译器继续前进 -
const refToElement = useRef(null);
if (refToElement && refToElement.current) {
// @ts-ignore: Object is possibly 'null'.
refToElement.current.focus();
}
Run Code Online (Sandbox Code Playgroud)
请注意,由于这是编译器错误而不是 linter 错误,// tslint:disable-next-line因此无效。此外,根据文档,这应该很少使用,仅在必要时使用
从 Typescript 3.7 开始,您可以使用optional chaining来解决上述问题 -
refToElement?.current?.focus();
Run Code Online (Sandbox Code Playgroud)
此外,有时可能只是将适当的类型传递给泛型参数,而使用useRef.
例如:如果是input元素 -
const refToElement = useRef<HTMLInputElement>(null);
Run Code Online (Sandbox Code Playgroud)
Blo*_*gic 28
要解决此问题,如果您确定在访问其属性时该对象不为空,则可以简单地使用感叹号:
list!.values
Run Code Online (Sandbox Code Playgroud)
乍一看,有些人可能会从角度上将其与安全导航操作符混淆,事实并非如此!
list?.values
Run Code Online (Sandbox Code Playgroud)
在!后修复的表达会告诉编译器TS变量不为空,如果这是不是会在运行时崩溃的情况下
对于useRef挂钩使用这样的
const value = inputRef?.current?.value
Run Code Online (Sandbox Code Playgroud)
Jos*_*ree 22
我用了:
if (object !== undefined) {
// continue - error suppressed when used in this way.
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用类型强制:
const objectX = object as string
Run Code Online (Sandbox Code Playgroud)
虽然在选择上述解决方法之一之前,请考虑您的目标架构,并对整体情况产生影响.
Mah*_*pal 15
这个解决方案对我有用:
小智 13
与“对象可能为空”编译错误相关,如果您想在打字稿配置中禁用此检查,您应该在文件中添加以下行tsconfig.json。
"compilerOptions": {
// other rules
"strictNullChecks": false
}
Run Code Online (Sandbox Code Playgroud)
ssu*_*ube 12
如果您知道类型将永远不会null或undefined,您应该声明它foo: Bar没有?.声明具有? Bar语法的类型意味着它可能未定义,这是您需要检查的内容.
换句话说,编译器正在完全按照您的要求进行操作.如果您希望它是可选的,您需要稍后检查.
这不是OP的问题,但是Object is possibly 'null'当我偶然将参数声明为null类型时,我收到了相同的消息:
something: null;
Run Code Online (Sandbox Code Playgroud)
而不是为其赋值null:
something: string = null;
Run Code Online (Sandbox Code Playgroud)
对我来说,这是一个错误ref和反应:
const quoteElement = React.useRef()
const somethingElse = quoteElement!.current?.offsetHeight ?? 0
Run Code Online (Sandbox Code Playgroud)
这会抛出错误,修复,给它一个类型:
// <div> reference type
const divRef = React.useRef<HTMLDivElement>(null);
// <button> reference type
const buttonRef = React.useRef<HTMLButtonElement>(null);
// <br /> reference type
const brRef = React.useRef<HTMLBRElement>(null);
// <a> reference type
const linkRef = React.useRef<HTMLLinkElement>(null);
Run Code Online (Sandbox Code Playgroud)
没有更多的错误,希望在某种程度上这可能会帮助其他人,甚至我将来:P
作为一种选择,您可以使用类型转换。如果您从打字稿中收到此错误,则意味着某些变量具有类型或未定义:
let a: string[] | undefined;
let b: number = a.length; // [ts] Object is possibly 'undefined'
let c: number = (a as string[]).length; // ok
Run Code Online (Sandbox Code Playgroud)
确保a代码中确实存在该代码。
我经常会拥有 类型的成员变量,并且直到(使用 Angular)Observable<string>我才会初始化它。ngOnInit然后编译器假设它未初始化,因为它没有“在构造函数中明确分配” - 并且编译器永远不会理解ngOnInit。
您可以在定义上使用!断言运算符来避免错误:
favoriteColor!: Observable<string>;
Run Code Online (Sandbox Code Playgroud)
未初始化的可观察对象可能会导致各种运行时痛苦,并出现诸如“您必须提供流但提供了 null”之类的错误。!如果您确实知道它将被设置为类似 的值,那么就可以了,但ngOnInit在某些情况下,该值可能会以其他不太确定的方式设置。
所以我有时会使用的另一种选择是:
public loaded$: Observable<boolean> = uninitialized('loaded');
Run Code Online (Sandbox Code Playgroud)
其中在uninitialized全局某处定义为:
export const uninitialized = (name: string) => throwError(name + ' not initialized');
Run Code Online (Sandbox Code Playgroud)
然后,如果您在未定义该流的情况下使用该流,它将立即引发运行时错误。
在 ReactJS 中,我检查构造函数中变量是否为空,如果是,我将其视为异常并适当地管理异常。如果变量不为空,代码将继续执行,并且编译器在此之后不会再抱怨:
private variable1: any;
private variable2: any;
constructor(props: IProps) {
super(props);
// i.e. here I am trying to access an HTML element
// which might be null if there is a typo in the name
this.variable1 = document.querySelector('element1');
this.variable2 = document.querySelector('element2');
// check if objects are null
if(!this.variable1 || !this.variable2) {
// Manage the 'exception', show the user a message, etc.
} else {
// Interpreter should not complain from this point on
// in any part of the file
this.variable1.disabled = true; // i.e. this line should not show the error
}
Run Code Online (Sandbox Code Playgroud)
从 TypeScript 3.7 ( https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html ) 开始,您现在可以?.在访问属性(或调用方法)时使用运算符来获取未定义) 在 null 或未定义的对象上:
inputEl?.current?.focus(); // skips the call when inputEl or inputEl.current is null or undefined
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
150748 次 |
| 最近记录: |