如果未预先检查数组是否为空,我希望打字稿编译器在尝试直接访问数组的任何元素时抛出“对象可能是未定义的”错误,以便您始终必须检查该元素对于未定义,例如,使用可选链
如果预先检查数组不为空,那么你需要能够像往常一样访问它的元素,而不需要检查它的元素是否为undefined
我需要这个是为了确保数组不是空的,所以如果它是空的,那么访问它的任何元素将立即返回 undefined 然后链接将不会继续并且不会有可能的错误,比如无法读取未定义的属性
我该怎么做?
代码示例,也许会让我的问题更清楚
interface Element {
a: {
aa: string;
bb: string;
};
b: {
aa: string;
bb: string;
};
}
const element: Element = {
a: { aa: "aa", bb: "bb" },
b: { aa: "aa", bb: "bb" },
};
type ElementArray = Element[];
const array: ElementArray = [element, element];
const emptyArray: ElementArray = [];
const getFirstAWithoutLengthCheck = (array: ElementArray) => {
return array[0].a; // i want the typescript compiler to throw an 'Object is possibly 'undefined'' error here
};
const getFirstAWithLengthCheck = (array: ElementArray) => {
if (array.length) {
return array[0].a; // shouldn't be any errors
}
return null;
};
const getFirstAOptChaining = (array: ElementArray) => {
return array[0]?.a; // shouldn't be any errors
};
// will throw error cannot read property a of undefined, so we need to use
// optional chaining or length check in this function, but typesript is not requiring it
console.log(getFirstAWithoutLengthCheck(array)); // aa
console.log(getFirstAWithoutLengthCheck(emptyArray)); // crash!
// checking array length, access to first element should work as usual, no errors
console.log(getFirstAWithLengthCheck(array)); // aa
console.log(getFirstAWithLengthCheck(emptyArray)); // null
// optional chaining, no errors
console.log(getFirstAOptChaining(array)); // aa
console.log(getFirstAOptChaining(emptyArray)); // undefined
答案 0 :(得分:1)
正如@Roberto Zvjerković 所评论的,您需要使用 noUncheckedIndexedAccess 编译器标志。
Playground(链接开启了 # Add two numbers layout code
BoxLayout:
spacing: 1
orientation:'vertical'
pos_hint: {'x': 0, 'y': 0}
background_color: .7,.7,.7,1
canvas.before:
Color:
rgba: .7, .7, .7, 1
Rectangle:
size: self.size
pos: self.pos
ColorLabel:
text: "Enter two numbers to add"
TextInput:
id: frnum
size_hint: (None, .8)
width: 150
anchor_x: 'center'
TextInput:
id: secnum
size_hint: (None, .8)
width: 150
anchor_x: 'center'
# horizontal box contains two buttons
BoxLayout:
spacing: 10
orientation:'horizontal'
canvas.before:
Color:
rgba: .7, .7, .7, 1
GrayButton:
text: 'Add'
color: 0,0,0,1
on_release:
app.bclick()
GrayButton:
text: 'Clear'
on_release:
app.cclick()
ColorLabel:
text: "Sum appears here"
id: sumlabel
<ColorLabel@Label>:
color: 0,0,1,1
size: self.texture_size
canvas.before:
Color:
rgba: .9, .9, .9, 1
Rectangle:
pos: self.pos
size: self.size
padding_x: 20
background_color: .7,.7,.7,1
<GrayButton@Button>:
color: 0,0,0,1
background_normal: ''
background_color: .8,.8,.8,1
padding_horizontal: 20
size_hint: (0.5,0.7)
pos_hint: {'x':.2, 'y':.2, 'center_x':.5}
from kivy.app import App
from kivy.core.window import Window
from kivy.config import Config
class MainApp(App):
def build(self):
#self.title = "Add two numbers"
Window.size = (300, 200)
self.load_kv('Bldtest1.kv')
# Add click event
def bclick(self):
textinput = self.root.ids.frnum
val1= int(textinput.text)
tinput = self.root.ids.secnum
val2 = int(tinput.text)
sum_label = self.root.ids.sumlabel
sum_label.text = "Sum is: "+ str(val1+val2)
# Clear button click event
def cclick(self):
textinput = self.root.ids.frnum
textinput.text = ''
tinput = self.root.ids.secnum
tinput.text = ""
sum_label = self.root.ids.sumlabel
sum_label.text =''
MainApp().run()
标志)。
但是,您需要使用 noUncheckedIndexedAccess
而不是 if (array.length)
,您需要执行 if (array[0])
。这是因为,即使长度不为零,也不能确保元素是“非未定义的”。如果数组是 array = [undefined]
,它应该给出运行时错误。是否可以包含 undefined
与数组类型无关。
答案 1 :(得分:0)
我设法让 TypeScript 在第一个示例中抛出错误,而在第三个示例中没有抛出错误,但遗憾的是它在第二个示例中为您提供了未定义的错误。希望这对您有所帮助:
interface Element {
a: {
aa: string;
bb: string;
};
b: {
aa: string;
bb: string;
};
}
const element: Element = {
a: { aa: "aa", bb: "bb" },
b: { aa: "aa", bb: "bb" },
};
type ElementArray = [] | [Element] | [Element, ...Element[]];
const array: ElementArray = [element, element];
const emptyArray: ElementArray = [];
const getFirstAWithoutLengthCheck = (array: ElementArray) => {
return array[0].a; // i want the typescript compiler to throw an 'Object is possibly 'undefined'' error here
};
const getFirstAWithLengthCheck = (array: ElementArray) => {
if (array.length) {
return array[0].a; // shouldn't be any errors
}
return null;
};
const getFirstAOptChaining = (array: ElementArray) => {
return array[0]?.a; // shouldn't be any errors
};
// will throw error cannot read property a of undefined, so we need to use
// optional chaining or length check in this function, but typesript is not requiring it
console.log(getFirstAWithoutLengthCheck(array)); // aa
console.log(getFirstAWithoutLengthCheck(emptyArray)); // crash!
// checking array length, access to first element should work as usual, no errors
console.log(getFirstAWithLengthCheck(array)); // aa
console.log(getFirstAWithLengthCheck(emptyArray)); // null
// optional chaining, no errors
console.log(getFirstAOptChaining(array)); // aa
console.log(getFirstAOptChaining(emptyArray)); // undefined
TypeScript playground 忽略元素上的错误,TypeScript playground 认为该元素是一个 DOM 元素