Javascript 混合类型映射函数中的类型脚本类型问题
我定义了两种类型,Javascript 混合类型映射函数中的类型脚本类型问题,javascript,reactjs,typescript,ecmascript-6,union-types,Javascript,Reactjs,Typescript,Ecmascript 6,Union Types,我定义了两种类型,Team和Position。它们都是我在react组件中迭代的数组的一部分 根据下面在mymap函数中定义的类型,我发现以下错误 我看到的错误示例 类型“Position”上不存在属性“name”。[2339] 类型“Team”上不存在属性“position”。[2339] 是否无法检查数组是否包含这两种类型 我的代码如下所示: type Team = { name: string; city: string; } type Position = { p
Team
和Position
。它们都是我在react组件中迭代的数组的一部分
根据下面在mymap
函数中定义的类型,我发现以下错误
我看到的错误示例
类型“Position”上不存在属性“name”。[2339]
类型“Team”上不存在属性“position”。[2339]
是否无法检查数组是否包含这两种类型
我的代码如下所示:
type Team = {
name: string;
city: string;
}
type Position = {
position: number;
}
const Component = () => {
const teamsAndPosition = [
{
name: 'Arsenal',
city: 'London',
},
{
name: 'Everton',
city: 'Liverpool',
},
{
position: 2
}
];
const [list, setList] = useState<Array<Team | Position >>(teams)
list.map((item: Team | Position) => {
return item.name ? (
<div>
// I am seeing an error for these below
<p>{item.name}</p>
<p>{item.city}</p>
</div>
) : (
<p>{item.position}</p>
)
})
}
类型团队={
名称:字符串;
城市:字符串;
}
类型位置={
职位:编号;
}
常量组件=()=>{
const teamsAndPosition=[
{
名称:“阿森纳”,
城市:“伦敦”,
},
{
名字:“埃弗顿”,
城市:“利物浦”,
},
{
职位:2
}
];
const[list,setList]=useState(团队)
列表.地图((项目:团队|位置)=>{
返回item.name(
//我在下面看到了一个错误
{item.name}
{item.city}
) : (
{item.position}
)
})
}
当处理可能是两种(或多种)类型之一的变量时,可以在处理对象之前检查对象上是否存在唯一属性,以便typescript可以推断它是什么类型
例如:
interface IObjectYo {
someProp: number
same: boolean
}
interface IDifObjYo {
otherProp: number
same: boolean
}
function example(someArg: IObjectYo | IDifObjYo) {
console.log(someArg.someProp) // tsc complains because someProp doesn't belong to IDifObjYo
if ('someProp' in someArg) {
console.log(someArg.someProp) // tsc knows it must be type IObjectYo because someProp only belongs to IObjectYo
} else {
console.log(someArg.otherProp) // tsc knows this is IDifObjYo because the first condition failed (which means it must be of type IDifObjYo)
}
if ('same' in someArg) {
console.log(someArg.someProp) // make sure the property is indeed unique between the possible types or tsc can't infer
}
}
在你的情况下(我不是一个反应型的人),你可以这样做:
type Team = {
name: string;
city: string
}
type Position = {
position: number;
}
const Component = () => {
const [list, setList] = useState<Array<Team | Position >>(teams)
list.map((item: Team | Position) => {
return 'name' in item ? (
<div>
<p>{item.name}</p>
<p>{item.city}</p>
</div>
) : (
<p>{item.position}</p>
)
})
}
类型团队={
名称:字符串;
城市:字符串
}
类型位置={
职位:编号;
}
常量组件=()=>{
const[list,setList]=useState(团队)
列表.地图((项目:团队|位置)=>{
是否在项目中返回“name”(
{item.name}
{item.city}
) : (
{item.position}
)
})
}
如果项目
可以是团队
或职位
那么你应该显示项目.名称
和项目.职位
或者,区分项目
的类型?这比我在这里发布的内容要复杂一些。我已经把这个问题的例子简化了。希望它仍然有意义:-D。基本上,我根据传入的对象显示了不同的元素/组件。但是数组可以包含我们的。责怪设计师:-)在这两种情况下,您都面临一种情况,即属性不存在。您可能希望使用?
可选属性扩展您的类型,或者执行{item.name?item.name:''}
@TitianCernicova Dragomir为您提供了一个很好的工作解决方案。另外,如果你有选择改变一些事情,你可以考虑做一个父类的团队成员和位置成员,然后以规范的方式调用属性,这样就不会有不能满足的请求。尽管如此,我还是会在尝试访问属性之前添加检查以确保属性可用,否则当数据不完整时,您将面临出错的风险。嗯,显然我感谢您的帮助,但我不确定我是否真的喜欢这两种解决方案中的任何一种。数组将始终包含一个。我将使用包含的数组更新问题。@peterflanagan,请在item中尝试'name'作为条件,而不是item.name
。如果这不起作用,那么您现在是遇到了相同的错误还是不同的错误?这似乎没有多大意义,可以处理更新后的问题?我现在已经包括了array@peterflanagan,有什么特别不合理<代码>“项目”中的“名称”检查属性是否存在,而不是属性本身;这就是为什么typescript会抱怨的原因。这现在起作用了,但我不认为它是当时的样子:-DGlad我可以帮助@peterflanagan。快乐编码!