使用打字稿非歧视工会
Working with typescript non-discriminated unions
我想知道是否有一种明智的方法可以使以下内容正常工作。
interface IPerson {
firstName: string
lastName: string
}
interface IPet {
name: string
}
type IPersonOrPet = IPerson | IPet
function fullname(p: IPersonOrPet) {
if (p.name) { // **1**
return p.name // **2**
} else {
return p.firstName + ' ' + p.lastName // **3**
}
}
我看到有歧视的工会,这些事情很简单,但我不明白为什么没有任何事情适用于非歧视的工会:
- 1 我可以想象,打字稿在这里抱怨是因为不知道
p.name
是否存在。但是没有比使用 any
更好的方法了吗?
- 2 但是,这里它知道它存在并且是非空的。这样的推论在很多地方都适用,为什么这里不行呢?
- 3 这显然是错误的,因为它是为了一只未命名的宠物(即
{name: ''}
)到达的。由于前两点不知道怎么解决,这里只能猜测了。
在 TypeScript 中解决这个问题的正确方法是使用类型保护,该函数的 return 类型确认或拒绝您的假设 p
属于 Person
或 Pet
。
检查 isPerson()
函数的 return 类型:
interface Person {
firstName: string
lastName: string
}
interface Pet {
name: string
}
type PersonOrPet = Person | Pet
function fullname(p: PersonOrPet) {
if (isPerson(p)) {
return p.firstName + ' ' + p.lastName;
} else {
return p.name;
}
}
function isPerson(p: PersonOrPet): p is Person {
return 'firstName' in p && 'lastName' in p;
}
您可以use the in
operator as a type guard将使用哪个打字稿来正确缩小条件体内的类型。
function fullname(p: IPersonOrPet) {
if ('name' in p) { // **1**
return p.name // **2**
} else {
return p.firstName + ' ' + p.lastName // **3**
}
}
我想知道是否有一种明智的方法可以使以下内容正常工作。
interface IPerson {
firstName: string
lastName: string
}
interface IPet {
name: string
}
type IPersonOrPet = IPerson | IPet
function fullname(p: IPersonOrPet) {
if (p.name) { // **1**
return p.name // **2**
} else {
return p.firstName + ' ' + p.lastName // **3**
}
}
我看到有歧视的工会,这些事情很简单,但我不明白为什么没有任何事情适用于非歧视的工会:
- 1 我可以想象,打字稿在这里抱怨是因为不知道
p.name
是否存在。但是没有比使用any
更好的方法了吗? - 2 但是,这里它知道它存在并且是非空的。这样的推论在很多地方都适用,为什么这里不行呢?
- 3 这显然是错误的,因为它是为了一只未命名的宠物(即
{name: ''}
)到达的。由于前两点不知道怎么解决,这里只能猜测了。
在 TypeScript 中解决这个问题的正确方法是使用类型保护,该函数的 return 类型确认或拒绝您的假设 p
属于 Person
或 Pet
。
检查 isPerson()
函数的 return 类型:
interface Person {
firstName: string
lastName: string
}
interface Pet {
name: string
}
type PersonOrPet = Person | Pet
function fullname(p: PersonOrPet) {
if (isPerson(p)) {
return p.firstName + ' ' + p.lastName;
} else {
return p.name;
}
}
function isPerson(p: PersonOrPet): p is Person {
return 'firstName' in p && 'lastName' in p;
}
您可以use the in
operator as a type guard将使用哪个打字稿来正确缩小条件体内的类型。
function fullname(p: IPersonOrPet) {
if ('name' in p) { // **1**
return p.name // **2**
} else {
return p.firstName + ' ' + p.lastName // **3**
}
}