网站搜索

typescript - 为可以有不同结构的对象参数定义类型


我有一个函数,它以一个对象作为参数,但传入的对象可能有不同的结构。如何为参数定义类型,而不必将对象的任何属性设置为可选(因为这会大大降低整个类型系统的作用)?

我想做的事情,但显然不行,是这样的:

type One = {
  a: string
  b: string
}

type Two = {
  c: string
  d: string
}

type Three = {
  e: string
}

type OneOfTheseTypes = One | Two | Three

const myGenericFunction = (obj: OneOfTheseTypes) => {...}

附言:我刚开始接触 TypeScript,所以如果我的想法完全不对,请多包涵!

编辑:所以这个函数返回一个与参数类型相同的对象,当我使用返回的对象(比如 returnedObj.a)时,会出现错误提示“属性 'a' 不存在于类型 'OneOfTheseTypes' 上。”以及“属性 'a' 不存在于类型 'Two' 上。”我在使用带 React 的 TypeScript,不知道这是否与此有关。

答案#1

你问题中的示例是可行的,并且你的示例中没有编译错误。你可以直接使用 generics 来轻松解决你的问题:

type One = {
  a: string
  b: string
}

type Two = {
  c: string
  d: string
}

type Three = {
  e: string
}

const myGenericFunction = <T>(obj: T): T => obj;

const testObject: One = {
  a: 'fieldA',
  b: 'FieldB'
};

myGenericFunction<One>(testObject);

关于泛型的更多信息。

答案#2

TypeScript 会显示正确的错误信息,指出 OneOfTheseTypes 上不存在 'a' 属性。但如果你确定,可以使用 as 操作符将结果类型转换为更具体的类型。

不过要小心:如果你的结果类型是Two或Three,你将会有运行时错误。

let one: One = {
    a: 'hi',
    b: 'bye'
}

let res = myGenericFunction(one);
(res as One).a; // OK