如何在存在多个接口的Factory模式中设置类型



有以下类型

interface A {
id: number
name: string
patternA: patternA[]
}
interface B {
id: number
name: string
patternB: patternB[]
}
interface C {
id: number
name: string
patternC: patternC[]
city: string
}

还有工厂方法

const factory = (type, data: /**    what should I write?? **/) => {
switch (type) {
case 'first':
return createHogeA(data)
case 'second':
return createHogeB(data)
case 'third':
return createHogeC(data)
default:
return
}
}
const createHogeA = (data: A) => somefunctionA(data)
const createHogeB = (data: B) => somefunctionB(data)
const createHogeC = (data: C) => somefunctionC(data)

到目前为止我尝试了什么

  1. 这样设置类型,但随后出现错误,因为每个数据类型都可能传递给每个函数
const factory = (type, data: A | B | C) => {
switch (type) {
case 'first':
return createHogeA(data)
case 'second':
return createHogeB(data)
case 'third':
return createHogeC(data)
default:
return
}
}
  1. 创建基本界面
interface base {
id: number
name: string
}

但老实说,我不知道

可能通过类型联合歧视:

interface A {
type: 'A'
id: number
name: string
patternA: patternA[]
}
interface B {
type: 'B'
id: number
name: string
patternB: patternB[]
}
interface C {
type: 'C'
id: number
name: string
patternC: patternC[]
city: string
}
type ABC = A | B | C;
const factory = (data: ABC) => {
switch (data.type) {
case 'A':
return createHogeA(data)
case 'B':
return createHogeB(data)
case 'C':
return createHogeC(data)
default:
return
}
}

处理此问题的最简单方法是使用as关键字告诉编译器data对象在调用任一函数时满足哪个接口。

const factory = (type: string, data: A | B | C) => {
switch (type) {
case 'first':
return createHogeA(data as A)
case 'second':
return createHogeB(data as B)
case 'third':
return createHogeC(data as C)
default:
return
}
}

您也可以使用防护来确定哪个接口data满足

const isA = (data: any): data is A => {
return (data as A).patternA !== undefined;
}
const isB = (data: any): data is B => {
return (data as B).patternB !== undefined;
}
const isC = (data: any): data is C => {
return (data as C).patternC !== undefined && (data as C).city !== undefined;
}
const factory = (_type: string, data: A | B | C) => {
if(isA(data)) {
createHogeA(data)
}
// Rest of code here
}

最新更新