"Not assignable to parameter of type never" Vue 存储数组声明中的 TS 错误
"Not assignable to parameter of type never" TS error in Vue store array declaration
我不明白为什么会出现此错误:
Argument of type '{ id: string; }' is not assignable to parameter of
type 'never'.
...在行 const index = state.sections.findIndex((section) => section.id === id);
在我的 Vue 商店的以下部分:
import { MutationTree, ActionTree, GetterTree } from 'vuex';
interface section {
id: string;
section_header: string;
section_body: string;
sectionItems: any;
}
interface sections extends Array<section>{}
export const state = () => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
type EditorState = ReturnType<typeof state>;
export const mutations: MutationTree<EditorState> = {
ADD_SECTION_ITEM(state, id) {
const index = state.sections.findIndex((section) => section.id === id);
const sectionItem = {
id: randomId()
}
state.sections[index].sectionItems.push(sectionItem);
},
};
我认为你需要 state.sections.push(sectionItem)
而不是 state.sections[index].sectionItems.push(sectionItems)
。
我会说你可能需要输入你的 sectionItems:
interface SectionItem {
id: string
}
interface Section {
id: string;
section_header: string;
section_body?: string;
sectionItems: SectionItem;
}
interface State {
sections: Section[]
}
export const state = (): State => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
type EditorState = ReturnType<State>;
export const mutations: MutationTree<EditorState> = {
ADD_SECTION_ITEM(state, id) {
const index = state.sections.findIndex((section) => section.id === id);
const sectionItem = {
id: randomId()
}
state.sections[index].sectionItems.push(sectionItem);
},
};
因为,当你没有指定 sectionItems 的类型时,typescript 会查看你在你的状态下初始化的 sectionItems(等于 []),并且无法识别应该在这个数组中的元素类型.
所以你定义它。
此外, section_body 应该是可选的,因为你的所有示例中都不存在它。
接口名称在打字稿中应大写。
此外,我认为您不需要版块界面。如果你想输入一些东西作为接口的数组,只需使用 section[] 作为类型,就像你做 string[].
最后,这取决于您,但我建议不要在您的界面(以及您的代码中)使用不同的命名约定:section_body 是 snake_case 并且 sectionItems 是驼峰式命名,它是通常最好坚持一个并将其保留在所有代码中。
已编辑,您需要使用描述它的接口状态来键入“状态”。
此外,我对 Vuex 没有太多的具体经验,但他们似乎指出了一种将它与 typescript 一起使用的特定方法,这与您正在做的不同:vuex docs here
当您不为值提供类型时——您的函数的 return 值,在这种情况下——TypeScript 会尝试将其缩小到最准确的类型。由于您的 returned 对象的 sections
' 项数组始终为空,因此它将它们推断为 never[]
(type[]
是 Array<type>
的别名);一个实际上不能包含任何值的数组。您可以在以下代码段中看到这一点:
const functionReturningEmptyArray = () => ({ items: [] });
type EmptyArray = ReturnType<typeof functionReturningEmptyArray>;
// type EmptyArray = { items: never[] }
解决此问题的一种方法是使用您创建的 section
接口来指定 state
的 return 类型。
export const state = (): { sections: Array<section> } => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
第一行空括号后的冒号指定函数的 return 类型。在这种情况下,我内联了对象类型,因为它只有一个 属性,但如果你的 state
更复杂,或者你只是喜欢可读性,你可以将它提取为一个单独的类型,并且将其引用为 return 类型;
interface MyState {
sections: Array<section>;
}
export const state = (): MyState => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
此时,TypeScript 将对您的 returned 值抛出错误,因为您的 section
接口指定该对象还应具有 section_body
属性 ,它在您的 returned sections
数组中缺失。要解决此问题,您可以给数组中的每个对象一个 section_body
属性,或者修改界面以匹配 属性 可能存在或不存在的事实;
interface section {
id: string;
section_header: string;
section_body?: string;
sectionItems: any;
}
您的商店现在应该没有错误了,但要获得更安全的类型 sectionItems
属性,您还可以将其从 any
更改为 Array<any>
,或者如果您事先知道部分项目的外观,请使用更具体的对象类型。
我不明白为什么会出现此错误:
Argument of type '{ id: string; }' is not assignable to parameter of type 'never'.
...在行 const index = state.sections.findIndex((section) => section.id === id);
在我的 Vue 商店的以下部分:
import { MutationTree, ActionTree, GetterTree } from 'vuex';
interface section {
id: string;
section_header: string;
section_body: string;
sectionItems: any;
}
interface sections extends Array<section>{}
export const state = () => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
type EditorState = ReturnType<typeof state>;
export const mutations: MutationTree<EditorState> = {
ADD_SECTION_ITEM(state, id) {
const index = state.sections.findIndex((section) => section.id === id);
const sectionItem = {
id: randomId()
}
state.sections[index].sectionItems.push(sectionItem);
},
};
我认为你需要 state.sections.push(sectionItem)
而不是 state.sections[index].sectionItems.push(sectionItems)
。
我会说你可能需要输入你的 sectionItems:
interface SectionItem {
id: string
}
interface Section {
id: string;
section_header: string;
section_body?: string;
sectionItems: SectionItem;
}
interface State {
sections: Section[]
}
export const state = (): State => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
type EditorState = ReturnType<State>;
export const mutations: MutationTree<EditorState> = {
ADD_SECTION_ITEM(state, id) {
const index = state.sections.findIndex((section) => section.id === id);
const sectionItem = {
id: randomId()
}
state.sections[index].sectionItems.push(sectionItem);
},
};
因为,当你没有指定 sectionItems 的类型时,typescript 会查看你在你的状态下初始化的 sectionItems(等于 []),并且无法识别应该在这个数组中的元素类型.
所以你定义它。 此外, section_body 应该是可选的,因为你的所有示例中都不存在它。 接口名称在打字稿中应大写。
此外,我认为您不需要版块界面。如果你想输入一些东西作为接口的数组,只需使用 section[] 作为类型,就像你做 string[].
最后,这取决于您,但我建议不要在您的界面(以及您的代码中)使用不同的命名约定:section_body 是 snake_case 并且 sectionItems 是驼峰式命名,它是通常最好坚持一个并将其保留在所有代码中。
已编辑,您需要使用描述它的接口状态来键入“状态”。
此外,我对 Vuex 没有太多的具体经验,但他们似乎指出了一种将它与 typescript 一起使用的特定方法,这与您正在做的不同:vuex docs here
当您不为值提供类型时——您的函数的 return 值,在这种情况下——TypeScript 会尝试将其缩小到最准确的类型。由于您的 returned 对象的 sections
' 项数组始终为空,因此它将它们推断为 never[]
(type[]
是 Array<type>
的别名);一个实际上不能包含任何值的数组。您可以在以下代码段中看到这一点:
const functionReturningEmptyArray = () => ({ items: [] });
type EmptyArray = ReturnType<typeof functionReturningEmptyArray>;
// type EmptyArray = { items: never[] }
解决此问题的一种方法是使用您创建的 section
接口来指定 state
的 return 类型。
export const state = (): { sections: Array<section> } => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
第一行空括号后的冒号指定函数的 return 类型。在这种情况下,我内联了对象类型,因为它只有一个 属性,但如果你的 state
更复杂,或者你只是喜欢可读性,你可以将它提取为一个单独的类型,并且将其引用为 return 类型;
interface MyState {
sections: Array<section>;
}
export const state = (): MyState => ({
sections: [
{
id: '1',
section_header: 'lorem',
sectionItems: []
},
{
id: '2',
section_header: 'ipsum',
sectionItems: []
}
]
});
此时,TypeScript 将对您的 returned 值抛出错误,因为您的 section
接口指定该对象还应具有 section_body
属性 ,它在您的 returned sections
数组中缺失。要解决此问题,您可以给数组中的每个对象一个 section_body
属性,或者修改界面以匹配 属性 可能存在或不存在的事实;
interface section {
id: string;
section_header: string;
section_body?: string;
sectionItems: any;
}
您的商店现在应该没有错误了,但要获得更安全的类型 sectionItems
属性,您还可以将其从 any
更改为 Array<any>
,或者如果您事先知道部分项目的外观,请使用更具体的对象类型。