[英]typeScript init dynamic class call by name (2345)
problem: (parameter) item: inputs Argument of type 'inputs' is not assignable to parameter of type 'ISelect & IText'.问题:(参数)项目:输入“输入”类型的参数不能分配给“ISelect & IText”类型的参数。 Type 'ISelect' is not assignable to type 'ISelect & IText'. “ISelect”类型不能分配给“ISelect & IText”类型。 Property 'placeholder' is missing in type 'ISelect' but required in type 'IText'.(2345) input.ts(12, 5): 'placeholder' is declared here.属性“占位符”在“ISelect”类型中缺失,但在“IText”类型中是必需的。(2345) input.ts(12, 5): 此处声明了“占位符”。
interface IInput {
id: number
title: string
}
interface ISelect extends IInput {
type: "inputSelect",
value: string
selects: string[]
}
interface IText extends IInput{
type: "inputText",
placeholder: string
value: string
}
type inputs = ISelect | IText
class InputSelect implements ISelect {
public id: number
public title: string
public value: string
public selects: string[]
public type: ISelect['type'] = "inputSelect"
constructor(
inputs: ISelect
) {
this.id = inputs.id
this.title = inputs.title
this.value = inputs.value
this.selects = inputs.selects
}
setValue(value: string) {
this.value = value
}
}
class InputText implements IText {
public id: number
public title: string
public value: string
public placeholder: string
public type: IText['type'] = "inputText"
constructor(
inputs: IText
) {
this.id = inputs.id
this.title = inputs.title
this.value = inputs.value
this.placeholder = inputs.placeholder
}
setValue(value: string) {
this.value = value
}
}
let b: inputs[] = [
{
id: 1,
title: "some select",
value: "",
selects: ["Moskow", "Bejing"],
type: "inputSelect"
},
{
id: 2,
title: "some text input",
value: "",
placeholder: "yourName",
type: "inputText"
}
]
const classes = {
inputText: InputText,
inputSelect: InputSelect
}
let a = b.map(item => new classes[item.type](item)) \\here error
console.log(a)
because the b
is a union of inputs you need to narrow it again in the map
function, unfortunately it's a limitation of typescript.因为b
是输入的联合,您需要在map
函数中再次缩小它的范围,不幸的是,这是 typescript 的限制。
let a = b.map(item =>
item.type === 'inputSelect' ? new classes[item.type](item) :
item.type === 'inputText' ? new classes[item.type](item) :
undefined
);
or you can do a dynamic type check, then you need only 1 condition on any amount of interfaces in the inputs
union.或者您可以进行动态类型检查,那么您只需要在inputs
联合中的任意数量的接口上满足 1 个条件。
const checker = <T extends inputs>(item: T, cl: unknown): cl is ({new (a: T): InstanceType<(typeof classes)[T['type']]>}) => {
return classes[item.type] === cl;
};
let a = b.map(item => {
const cl = classes[item.type];
return checker(item, cl) ? new cl(item) : undefined;
}).filter((v): v is NonNullable<typeof v> => !!v);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.