我想声明一个类型,该类型要求将给定类型T
的所有键都包含在数组中,例如:
checkKeys<T>(arr: Array<keyof T>): void {
// do something
}
interface MyType {
id: string;
value: number;
}
当前,如果调用checkKeys<MyType>
,则TS如果包含MyType
(id | value
)的任何键,则将认为传递的值有效:
checkKeys<MyType>(['id', 'value']); // valid
checkKeys<MyType>(['id']); // valid
checkKeys<MyType>(['id', 'values']); // invalid
是否可能要求在数组中指定所有键?
答案 0 :(得分:3)
您不能使用数组类型来做到这一点(至少我不知道一种将键的并集扩展为元组类型的方法,可能我只是不知道一种方法)。一种替代方法是使用对象文字来实现类似的效果。语法较为冗长,但是编译器将验证仅指定了正确的键。我们将使用Record
映射类型,并且可以将0
文字类型用于值,因为只有键才重要。
function checkKeys<T>(o: Record<keyof T, 0>): void {
// do something
}
interface MyType {
id: string;
value: number;
}
checkKeys<MyType>({ id: 0, value: 0 }); // valid
checkKeys<MyType>({ id: 0 }); // invalid
checkKeys<MyType>({ id: 0, values: 0 }); // invalid
答案 1 :(得分:2)
我找到了一种解决方法,但实际上该解决方案并不完美:
isMyTypeArr
这个想法是创建一个实现初始接口的简单对象。我们需要该对象以便获得其密钥长度,以便在length
Type Guard中进行比较。 Type Guard只是比较数组的长度-如果它们的长度相同,则意味着您提供了所有属性。
修改
添加了另一个类似的(更通用的)解决方案-主要区别在于:
T
属性(因为基本上是构造函数),我们可以在Type Guard中使用它; T
,因为已编译的JS删除了所有类型信息,因此我们无法使用interface IMyType {
id: string;
value: number;
}
class MyType implements IMyType {
constructor(public id: string = '', public value: number = 0) {}
}
type ArrType<T> = Array<keyof T>;
function isMyTypeArr<T>(arg: ArrType<T>, TClass: new () => T): arg is ArrType<T> {
return arg.length === TClass.length;
}
function checkKeys<T>(arr: ArrType<T>, TClass: new () => T): void {
if (isMyTypeArr<T>(arr, TClass)) {
console.log(arr.length);
// some other stuff
}
}
checkKeys<MyType>(['id', 'x'], MyType); // TS error
checkKeys<MyType>(['id'], MyType); // no console because of Type Guard
checkKeys<MyType>(['id', 'value'], MyType); // SUCCESS: console logs '2'
来实现check this post for more deta 这是最终的解决方案:
LayoutDocument layoutDocument = new LayoutDocument { Title = "Plan Layout" };
Window mainWindow = Application.Current.Windows.OfType<Window>().Where(x => x.Name == "MainWindow").FirstOrDefault();
if (mainWindow != null)
{
mainWindow.mainPanel.Children.Add(layoutDocument);
}
请注意,这些示例均基于TypeScript issue 13267
p.s。还创建了两个示例的stackblitz demo