我需要定义一个函数,它接受这种类型的对象:
interface Source<A> {
[index: string]: A
}
并转换该对象,保留键,但替换值:
interface Target<B> {
[index: string]: B
}
我也希望为这种情况保持类型检查。这是一个例子:
function transform(source) {
var result = {}
Object.keys(source).forEach((key) => {
result[key] = source[key] + "prefix"
})
}
var target = transform({
"key1": 1,
"key2": 2,
})
// now target has a {"key1": "1prefix", "key2": "2prefix"}
var three = target.key3 // I want to get type error here on compile-time
答案 0 :(得分:1)
现在可以使用keyof
关键字。
type Mock<K, T> = {
[P in keyof K]: T
}
这将创建一个具有K
类型的所有属性的类型,但这些属性的值类型将为T
。
然后,您可以修改函数以返回Mock<A, B>
,编译器会强制执行它。
答案 1 :(得分:0)
我不完全确定你在这之后是什么。你可以这样做:
interface Source<U> {
[index: string]: U
}
var transform = <U>(source: Source<U>) : Source<string> => {
var result: Source<string> = {}
Object.keys(source).forEach((key) => {
result[key] = source[key] + "prefix"
})
return result;
}
var target = transform({ "key1": 1, "key2": 2 });
// will give error "Type 'string' is not assignable to 'number'"
var blah: number = target["key1"];
// will work (compile and run)..
var blah2: string = target["key1"];
// will compile but crash at run time
var blah2: string = target["random string"];
// will not compile 'Property 'key1' does not exist on type 'Source<string>'
var blah2: string = target.key1;
最后一个案例永远不会编译。 Typescript在编译时运行所有类型检查。打字稿无法知道存在target['key1']
属性。如果这就是你想要的,那就没有办法让它发挥作用。
答案 2 :(得分:0)
一般情况下是不可能的。
TypeScript编译器没有,并且在所有情况下都没有足够的信息来检查您的代码。
答案 3 :(得分:0)
您添加到函数中的类型信息应与其承诺履行的合同相匹配。在原始示例中(此处调整为返回result
对象),您可以使用source
any
类型。
function transform(source) {
var result = {}
Object.keys(source).forEach((key) => {
result[key] = source[key] + "suffix";
});
return result;
}
如果您想要进行严格的类型检查,则需要更明确地说明:
interface A {
key1: number;
key2: number;
}
interface B {
key1: string;
key2: string;
}
function transformAtoB(a: A) : B {
return <B>transform(a);
}
在上面的示例中,因为您知道输入类型A
具有名为key1
和key2
的属性,所以您可以保证返回具有相同属性名称的对象(但不同类型) )。
您可以通过创建一个通用接口来减少接口数量:
interface A<T> {
key1: T;
key2: T;
}
function transformAtoB(a: A<number>) : A<string> {
return <A<string>>transform(a);
}
结果是你有完整的类型信息,这将抓住以下错误:
var target = transformAtoB({
"key1": 1,
"key2": 2,
});
console.log(target.key1);
console.log(target.key2);
console.log(target.key3); // Compiler warning