Typescript 接口属性依赖于其他属性

Typescript 接口属性依赖于其他属性,typescript,Typescript,假设我有下一个界面: interface TestInterface { id?: string; type?: string; } 是否可以在执行检查时重写id!==未定义它将自动意味着类型属性也已定义?您可以用联合类型来模拟这一点 简单的例子: 接口不可用{ id:字符串; 类型:字符串; } 界面不稳定{ id?:未定义; 类型?:未定义; } 类型FinalType=不可用|不可用; 函数testIdx:FinalType { 如果x.id!==未定义{ x、 类型//字符串

假设我有下一个界面:

interface TestInterface {
  id?: string;
  type?: string;
}

是否可以在执行检查时重写id!==未定义它将自动意味着类型属性也已定义?

您可以用联合类型来模拟这一点

简单的例子:

接口不可用{ id:字符串; 类型:字符串; } 界面不稳定{ id?:未定义; 类型?:未定义; } 类型FinalType=不可用|不可用; 函数testIdx:FinalType { 如果x.id!==未定义{ x、 类型//字符串 } } FinalType是可选的,您只需在任何地方使用x:inonnulable | INullable即可

添加类型保护功能:

您还可以使用type guard创建函数来测试您的条件,并通过以下方式缩小类型:

interface INonNullable {
    id: string;
    type: string;
}
interface INullable {
    id?: undefined;
    type?: undefined;
}
type FinalType = INonNullable | INullable;

function isNonNullable(x: FinalType): x is INonNullable
{
  return x.id !== undefined;
}

let x = {};

if (isNonNullable(x)) {
  x.type // string;
}
您可以在Typescript文档中了解更多信息:

可重复使用的空:

Patrick Roberts在评论中提到的另一个简洁的选项是,使用映射类型和泛型生成更可重用的解决方案:

接口不可用{ id:字符串; 类型:字符串; } 类型为空={ [K in keyof T]?:未定义; } 类型FinalType=T |空; 函数testIdx:FinalType{ 如果x.id!==未定义{ x、 类型//字符串 } }
可以使用联合类型来模拟这一点

简单的例子:

接口不可用{ id:字符串; 类型:字符串; } 界面不稳定{ id?:未定义; 类型?:未定义; } 类型FinalType=不可用|不可用; 函数testIdx:FinalType { 如果x.id!==未定义{ x、 类型//字符串 } } FinalType是可选的,您只需在任何地方使用x:inonnulable | INullable即可

添加类型保护功能:

您还可以使用type guard创建函数来测试您的条件,并通过以下方式缩小类型:

interface INonNullable {
    id: string;
    type: string;
}
interface INullable {
    id?: undefined;
    type?: undefined;
}
type FinalType = INonNullable | INullable;

function isNonNullable(x: FinalType): x is INonNullable
{
  return x.id !== undefined;
}

let x = {};

if (isNonNullable(x)) {
  x.type // string;
}
您可以在Typescript文档中了解更多信息:

可重复使用的空:

Patrick Roberts在评论中提到的另一个简洁的选项是,使用映射类型和泛型生成更可重用的解决方案:

接口不可用{ id:字符串; 类型:字符串; } 类型为空={ [K in keyof T]?:未定义; } 类型FinalType=T |空; 函数testIdx:FinalType{ 如果x.id!==未定义{ x、 类型//字符串 } } 让我们看看你的例子:

interface TestInterface {
  id?: string;
  type?: string;
}

const objectForTest: TestInterface = {
  id: '12345',
  type: 'some type'
}
您可以通过以下方式执行此操作:

1 objectForTest?.id

如果此运算符遇到undefined,它将返回此值而不会抛出TypeError

这等于:

const testValue = (objectForTest === null || objectForTest === undefined) ?
    undefined 
    :
    objectForTest.id;
2 objectForTest!。身份证

在这种情况下,您对类型检查器说:嘿,我向您保证objectForTest不是空的或未定义的。

让我们看看您的示例:

interface TestInterface {
  id?: string;
  type?: string;
}

const objectForTest: TestInterface = {
  id: '12345',
  type: 'some type'
}
您可以通过以下方式执行此操作:

1 objectForTest?.id

如果此运算符遇到undefined,它将返回此值而不会抛出TypeError

这等于:

const testValue = (objectForTest === null || objectForTest === undefined) ?
    undefined 
    :
    objectForTest.id;
2 objectForTest!。身份证


在这种情况下,您对类型检查器说:嘿,我向您保证objectForTest不是空的或未定义的。

这里有一种方法可以实现您想要的功能,使用union:

interface IdWithType {
  id: string;
  type: string;
}

interface WithoutId {
  id?: never;
  type?: string;
}

type TestInterface = IdWithType | WithoutId

// You cannot instansiate an object of type TestInterface with an id and with out a type

const yo: TestInterface = { // Type '{ id: string; }' is not assignable to type 'TestInterface'.
  id: "hey"
}


const testFunction = (a: TestInterface) => {
  if (a.id) {
    const b = a.type // string
  }
  const c = a.type // string | undefined
}

下面是一种使用union实现您想要的功能的方法:

interface IdWithType {
  id: string;
  type: string;
}

interface WithoutId {
  id?: never;
  type?: string;
}

type TestInterface = IdWithType | WithoutId

// You cannot instansiate an object of type TestInterface with an id and with out a type

const yo: TestInterface = { // Type '{ id: string; }' is not assignable to type 'TestInterface'.
  id: "hey"
}


const testFunction = (a: TestInterface) => {
  if (a.id) {
    const b = a.type // string
  }
  const c = a.type // string | undefined
}

这是一个很好的答案。对于更通用的方法,您甚至可以定义一个通用类型。这是一个很好的答案。对于更通用的方法,您甚至可以定义一个通用类型。