我的类型安全查询构建器中具有以下数据类型。
// types
type SUDI = S | U | D | I
type SUD = S | U | D
type S = 'Select'
type U = 'Update'
type D = 'Delete'
type I = 'Insert'
// states
interface STATE_SUDI { state: 'SUDI' }
interface STATE_SUD { state: 'SUD' }
interface STATE_S { state: 'S' }
interface STATE_U { state: 'U' }
interface STATE_D { state: 'D' }
interface STATE_I { state: 'I' }
您可以在类型和状态之间进行转换。
type TypeToState<T> =
SUDI extends T ? STATE_SUDI :
SUD extends T ? STATE_SUD :
S extends T ? STATE_S :
U extends T ? STATE_U :
D extends T ? STATE_D :
I extends T ? STATE_I : never;
type StateToType<T> =
T extends STATE_SUDI ? SUDI :
T extends STATE_SUD ? SUD :
T extends STATE_S ? S :
T extends STATE_U ? U :
T extends STATE_D ? D :
T extends STATE_I ? I : never;
状态数组的类型是所有状态类型的并集的数组。例如:
declare let array: (STATE_SUDI | STATE_SUD)[]
当数组元素的类型与StateToType
映射时,它变为:
StateToType<STATE_SUDI | STATE_SUD>
// = StateToType<STATE_SUDI> | StateToType<STATE_SUD>
// = SUDI | SUD
// = (S | U | D | I) | (S | U | D)
// = (S | U | D | I)
// = SUDI
我想要的行为是在联合的每个成员上应用StateToType
,然后得到交点。
BetterStateToType<test>
// = StateToType<STATE_SUDI> & StateToType<STATE_SUD>
// = SUDI & SUD
// = (S | U | D | I) & (S | U | D)
// = (S | U | D)
// = SUD
我需要定义BetterStateToType
的帮助。
我知道可以将并集转换为相交,但是我无法弄清楚是否还可以在相交之前应用映射。
答案 0 :(得分:1)
是的,这是可能的:
type BetterStateToType<T> =
(T extends any ? ((x: [StateToType<T>]) => void) : never) extends
((x: [infer I]) => void) ? I : never
type StateToTypeSuSussudio = BetterStateToType<STATE_SUDI | STATE_SUD>;
// = SUDI & SUD
// = (S | U | D | I) & (S | U | D)
// = (S | U | D)
// = SUD
// = "Select" | "Update" | "Delete"
它类似于常规的联合路口代码:
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
但是它使用U
代替[StatetoType<T>]
,而[SUDI] | [SUD]
变成了SUDI | SUD
之类的东西。单元素元组“框”阻止编译器评估SUDI
,而[SUDI] | [SUD]
立即折叠为never
,而type NotSure = BetterStateToType<STATE_S | STATE_U>
// = "Select" & "Update", not gonna happen
则保持不变,直到并集相交发生为止。>
我猜您对这样的StateToType<>
类似结果感到满意:
type StateTypeMap = {
SUDI: SUDI
SUD: SUD
S: S
U: U
D: D
I: I
}
type StateToType<T extends { state: keyof StateTypeMap }> =
StateTypeMap[T['state']];
顺便说一句,如果我不必使用条件类型,我倾向于避免使用条件类型,因此我更倾向于像这样定义 public override void Initialize(AnalysisContext context)
{
context.RegisterCompilationAction(AnalyzeCompilation);
}
private void AnalyzeCompilation(CompilationAnalysisContext context)
{
var compilation = context.Compilation;
int referenceCount = compilation.References.Count();
if (referenceCount > 1)
{
context.ReportDiagnostic(Diagnostic.Create(Rule, null, compilation.AssemblyName, referenceCount));
}
}
:
SELECT SDO_UTIL.TO_WKBGEOMETRY (GEOMETRY),
S_ROUTE,
BLOCK_ID
FROM GEOM_TABLE;
我想这大致相同。
希望有所帮助;祝你好运!