給定一個場景,我希望能夠“標記”從各種來源進入我的系統的資料,如果給定一些提供此映射的“源”函式,我該如何將此源資訊添加到我的系統中的任何型別 T
我想將此標記資訊附加到的資料的形狀并不特別重要——我希望我的 API 的用戶關心的是提供一個函式,該函式將使用他們的型別 T 來確定源的來源,然后是新聯合型別的簡單翻譯函式。
我試過做這樣的事情:
enum TAG {
EXTERNAL_SYSTEM_A,
EXTERNAL_SYSTEM_B,
EXTERNAL_SYSTEM_C,
UNKNOWN
}
interface TAGSource {
sourceTypes: TAG | TAG[];
}
// This can be literally any type at all
interface ExternalEntity {
name: string;
}
interface CalendarEntity{
id: number;
}
type SourceTagged<T> = T & TAGSource;
abstract class SourceTagMapper {
tagEntity<T>(entity: T): SourceTagged<T> {
return { sourceTypes: this.mapSourceTypes(entity), ...entity };
}
protected abstract mapSourceTypes<T>(entity: T): TAG | TAG[];
}
// Example user implementation
class ExternalEntitySourceTagMapper extends SourceTagMapper{
mapSourceTypes<ExternalEntity>(entity: ExternalEntity): TAG | TAG[] {
// Error: Property 'name' does not exist on type 'ExternalEntity'
console.log(entity.name);
// do some work to map external entity to a tag
return TAG.EXTERNAL_SYSTEM_A;
}
}
// Example user implementation
class CalendarEntitySourceTagMapper extends SourceTagMapper {
mapSourceTypes<CalendarEntity>(entity: CalendarEntity): TAG | TAG[] {
// Error: Property 'id' does not exist on type 'CalendarEntity'
console.log(entity.id);
return [TAG.EXTERNAL_SYSTEM_B, TAG.EXTERNAL_SYSTEM_C];
}
}
但是這種方法的問題是由于在運行時擦除了型別資訊,我在 mapSourceTypes 函式中沒有得到型別資訊。我正在努力想出一種設計,讓用戶能夠只提供一個映射功能,然后提供一個功能來“提供”這個映射以及添加的型別資訊給他們。
我嘗試從具有通用函式的抽象類繼承,但在我的基類中丟失了型別資訊,但由于型別擦除,我的派生類中不再存在這些屬性。任何改進的想法或考慮將不勝感激。
uj5u.com熱心網友回復:
泛型應該在類上,而不是方法上!這允許您擴展具有指定型別的泛型類。
abstract class SourceTagMapper<T> {
tagEntity(entity: T): SourceTagged<T> {
return { sourceTypes: this.mapSourceTypes(entity), ...entity };
}
protected abstract mapSourceTypes(entity: T): TAG | TAG[];
}
// Example user implementation
class ExternalEntitySourceTagMapper extends SourceTagMapper<ExternalEntity>{
mapSourceTypes(entity: ExternalEntity): TAG | TAG[] {
// Error: Property 'name' does not exist on type 'ExternalEntity'
console.log(entity.name);
// do some work to map external entity to an lvc type
return TAG.EXTERNAL_SYSTEM_A;
}
}
// Example user implementation
class CalendarEntitySourceTagMapper extends SourceTagMapper<CalendarEntity> {
mapSourceTypes(entity: CalendarEntity): TAG | TAG[] {
// Error: Property 'id' does not exist on type 'CalendarEntity'
console.log(entity.id);
return [TAG.EXTERNAL_SYSTEM_B, TAG.EXTERNAL_SYSTEM_C];
}
}
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/530725.html
