我想强制执行一个(编译时)约束,即T2
类型的变量可赋值给T1
类型的变量。
如果我有t2
类型的值(T2
),那么我可以执行以下操作:
const t1: T1 = t2;
有更好的方法吗?最好不必创建额外的运行时实体。
我没有直接在我的应用程序中定义这些类型中的任何一种,因此我不能将其中一种类型作为其他类型的超类。
答案 0 :(得分:1)
如果T2
无法分配给T1
而没有在运行时发出任何内容,您是否正在寻找会给您编译错误的见证人?当然,你可以定义这样的东西:
type ExtendsWitness<U extends T, T> = U
并像这样使用它:
type T2Witness = ExtendsWitness<T2, T1>
如果T2
可分配给T1
,则不会出现任何错误。否则,您将在ExtendsWitness
的第一个类型参数上收到错误,指出T2
不符合约束T1
。
以下是一些具体类型的示例:
interface Super {
foo: string;
bar: number;
}
interface GoodSub {
foo: 'a';
bar: 3;
baz: boolean;
}
type GoodWitness = ExtendsWitness<GoodSub, Super> // okay
请注意GoodSub
未定义为Super
,但编译器见证GoodSub
是Super
的子类型。这是一个坏子类型的例子:
interface BadSub {
foo: string;
baz: boolean;
}
type BadWitness = ExtendsWitness<BadSub, Super> // error
编译器无法见证BadSub
是Super
的子类型,错误会告诉您问题的确切原因:Type 'BadSub' does not satisfy the constraint 'Super'. Property 'bar' is missing in type 'BadSub'.
希望有所帮助;祝你好运!
答案 1 :(得分:0)
我不认为你想要的东西是可以实现的。抱歉这个愚蠢的句子,但只要你不能定义类型的相对性=&gt;你不能定义类型的相对性。
但是,您仍然有以下选项:
使用any
类型只需指定值
const t1: T1 = <any>t2;
const t3: T2 = <any>t1;`
具有施法者功能的类似解决方案:
function toT1(t: T2): T1 {
return <any>t;
}
const t1 = toT1(t2);
优点是您不需要定义t1类型。
创建一种将两种类型合并为一种
的类型type T3 = T1 | T2;
const t1: T3 = t2;
这解决了赋值问题,但可能导致已经绑定到T1和T2的实体出现一些问题。这可以根据需要在情境中使用
创建自定义类型后卫:
interface T1 { a: any; }
interface T2 { b: any; }
function isT1(t: T1 | T2): t is T1 {
return true;
}
const t2: T2 = { b: 1 };
const t1: T1 = isT1(t2) ? t2 : null;
这会一直返回true,因此您可以将变量分配给t1
而不会出现任何问题。然而,这仍然是丑陋的。
我会选择1号方式。它很简单,完全可以满足您的需求。过度工程也很糟糕。