我遇到了这个打字稿错误
Property 'id' does not exist on type 'never'.
我在这里制作了一个简化的示例(code sandbox here)
interface Get {
id: number;
}
interface Delete {
id: number;
}
const isGet = (narrowMe: Get | Delete, narrowBy: string): narrowMe is Get =>
narrowBy === "GET";
const isDel = (narrowMe: Get | Delete, narrowBy: string): narrowMe is Delete =>
narrowBy === "DELETE";
const foo = (narrowMe: Get | Delete, narrowBy: string) => {
if (isGet(narrowMe, narrowBy)) {
return narrowMe.id;
}
if (isDel(narrowMe, narrowBy)) {
return narrowMe.id; // error happens here
}
};
真正的代码更加复杂,但是从本质上讲,我认为问题在于上面的两个接口是相同的。如果我在Get
界面中添加了一个假字段,以使其与众不同,那么该错误就会消失。我正在努力寻找有关此处发生的情况以及如何解决或解决它的文档。添加伪字段是很麻烦的,除非没有其他方法,否则我真的不想将Get
和Delete
合并为共享类型。
答案 0 :(得分:0)
Get
和Delete
接口是一回事。 TypeScript有一种称为鸭子类型的内容,因此在检查narrowMe
是否符合Get
接口之后,TS知道它也符合Delete
接口,因此第二个if
是永远不可能。诸如此类的事情通常可以通过判别来解决:
interface Get {
type: 'get';
id: number;
}
interface Delete {
type: 'delete';
id: number;
}
我同意它看起来确实很黑,但这只是TypeScript类型系统的本质。如果两个接口相同,则它们描述相同的可能对象集。它们的名称无关紧要,您必须以其他方式对其进行区分。
interface Get {
type: 'get';
id: number;
}
interface Delete {
type: 'delete';
id: number;
}
const isGet = (narrowMe: Get | Delete): narrowMe is Get =>
narrowMe.type === "get";
const isDel = (narrowMe: Get | Delete): narrowMe is Delete =>
narrowMe.type === "delete";
const foo = (narrowMe: Get | Delete, narrowBy: string) => {
if (isGet(narrowMe)) {
return narrowMe.id;
} else if (isDel(narrowMe)) {
return narrowMe.id; // no error, narrowMe is of type Delete
}
};
答案 1 :(得分:0)
问题在于,这种使用类型保护的方式不是他们想要的,因此会以意外的方式表现。
最简单的解决方案是将您的逻辑不基于类型防护,而是基于arrowBy变量:
model = Sequential()
model.add(LSTM(units = 100, return_sequences = True))
model.add(Dropout(0.2))
model.add(LSTM(units=1000 , return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=1000 , return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=100))
model.add(Dropout(0.2))
model.add(Dense(units=1 ))
model.compile(optimizer=opt, loss='mean_squared_error' , metrics=[tf.keras.metrics.RootMeanSquaredError()])