Typescript 类型脚本查找/条件类型和联合

Typescript 类型脚本查找/条件类型和联合,typescript,union,conditional-types,Typescript,Union,Conditional Types,我有一个简单的问题:是否有可能在TypeScript中获得联合的一部分的类型 例如,您通常可以使用如下查找类型: interface Person { name: string; } type Name = Person['name'] type Entity = { __type: 'Company', name: string } | { __type: 'Employee', firstName: string }; type Company = DoTheMag

我有一个简单的问题:是否有可能在TypeScript中获得联合的一部分的类型

例如,您通常可以使用如下查找类型:

interface Person {
  name: string;
}

type Name = Person['name']
type Entity = 
    { __type: 'Company', name: string } 
  | { __type: 'Employee', firstName: string };
type Company = DoTheMagic<Entity, { __type: 'Employee' }> 

const company: Company = ...;

console.log(company.name) // OK
console.log(company.firstName) // Compile error
现在,我假设这样的工会是不可能的:

interface Person {
  name: string;
}

type Name = Person['name']
type Entity = 
    { __type: 'Company', name: string } 
  | { __type: 'Employee', firstName: string };
type Company = DoTheMagic<Entity, { __type: 'Employee' }> 

const company: Company = ...;

console.log(company.name) // OK
console.log(company.firstName) // Compile error
那么,有没有办法获得工会的一部分呢?大概是这样的:

interface Person {
  name: string;
}

type Name = Person['name']
type Entity = 
    { __type: 'Company', name: string } 
  | { __type: 'Employee', firstName: string };
type Company = DoTheMagic<Entity, { __type: 'Employee' }> 

const company: Company = ...;

console.log(company.name) // OK
console.log(company.firstName) // Compile error
type Company=DoTheMagic
常数公司:公司=。。。;
console.log(company.name)//确定
console.log(company.firstName)//编译错误

我们可以使用条件类型
Extract
。如果
T
是一个联合体,则
Extract
的结果将是
T
联合体中满足约束
U
(也称为
T扩展U
)的所有成员

type Company=Extract
//同
类型公司={
__类型:“员工”;
名字:字符串;
}

我们可以使用条件类型
Extract
。如果
T
是一个联合体,则
Extract
的结果将是
T
联合体中满足约束
U
(也称为
T扩展U
)的所有成员

type Company=Extract
//同
类型公司={
__类型:“员工”;
名字:字符串;
}
正确答案由Titian Cernicova Dragomir发布。 然而,我决定发布一个完整的解决方案来解决我更广泛的问题

我们正在与阿波罗的客户合作,我们经常收到一封电子邮件。由于强大的类型,您需要许多恶劣的条件来访问正确的属性并保持TypeScript的愉快

因此,我提出了以下asTypeGuard函数:

function asTypeGuard<Typename extends string>(typename: Typename) {
  return function<Entity extends { __typename: string }>(
    entity: Entity
  ): entity is Extract<Entity, { __typename: typeof typename }> {
    return entity.__typename === typename;
  };
}

const isCompany = asTypeGuard('Company');
const isEmployee = asTypeGuard('Employee');

let entity: { __typename: 'Company'; name: string } | { __typename: 'Employee'; firstName: string };

if (isCompany(entity)) {
  console.log(entity.name);
  console.log(entity.firstName) // Property 'firstName' does not exist on type '{ __typename: "Company"; name: string; }
} else if (isEmployee(entity)) {
  console.log(entity.name);     // Property 'name' does not exist on type '{ __typename: "Employee"; firstName: string; }
  console.log(entity.firstName)
}
函数asTypeGuard(typename:typename){
返回函数(
实体:实体
):实体是提取的{
返回实体。\uuuTypeName===typename;
};
}
const isCompany=asTypeGuard(“公司”);
const isEmployee=asTypeGuard(“员工”);
let实体:{uuuu typename:'Company';name:string}{{uuu typename:'Employee';firstName:string};
if(公司(实体)){
console.log(entity.name);
console.log(entity.firstName)//类型{{uuuu typename:“公司”;name:string;}上不存在属性“firstName”
}其他如果(员工(实体)){
console.log(entity.name);//类型“{uuuu typename:”Employee;firstName:string;”上不存在属性“name”
console.log(entity.firstName)
}
正确答案由Titian Cernicova Dragomir发布。 然而,我决定发布一个完整的解决方案来解决我更广泛的问题

我们正在与阿波罗的客户合作,我们经常收到一封电子邮件。由于强大的类型,您需要许多恶劣的条件来访问正确的属性并保持TypeScript的愉快

因此,我提出了以下asTypeGuard函数:

function asTypeGuard<Typename extends string>(typename: Typename) {
  return function<Entity extends { __typename: string }>(
    entity: Entity
  ): entity is Extract<Entity, { __typename: typeof typename }> {
    return entity.__typename === typename;
  };
}

const isCompany = asTypeGuard('Company');
const isEmployee = asTypeGuard('Employee');

let entity: { __typename: 'Company'; name: string } | { __typename: 'Employee'; firstName: string };

if (isCompany(entity)) {
  console.log(entity.name);
  console.log(entity.firstName) // Property 'firstName' does not exist on type '{ __typename: "Company"; name: string; }
} else if (isEmployee(entity)) {
  console.log(entity.name);     // Property 'name' does not exist on type '{ __typename: "Employee"; firstName: string; }
  console.log(entity.firstName)
}
函数asTypeGuard(typename:typename){
返回函数(
实体:实体
):实体是提取的{
返回实体。\uuuTypeName===typename;
};
}
const isCompany=asTypeGuard(“公司”);
const isEmployee=asTypeGuard(“员工”);
let实体:{uuuu typename:'Company';name:string}{{uuu typename:'Employee';firstName:string};
if(公司(实体)){
console.log(entity.name);
console.log(entity.firstName)//类型{{uuuu typename:“公司”;name:string;}上不存在属性“firstName”
}其他如果(员工(实体)){
console.log(entity.name);//类型“{uuuu typename:”Employee;firstName:string;”上不存在属性“name”
console.log(entity.firstName)
}
@Deftomat:))我做我的best@Deftomat)我尽力了