你不能自动完成.最大的阻碍是当前有
no type operator允许你在类型级别附加字符串文字,所以你甚至无法描述你正在做的转换:
// without Append, you can't type this:
function appendChange(originalKey: T): Append {
return originalKey+'Change';
}
这个功能有一个suggestion,但谁知道它是否会发生.
这意味着如果你想转换键,你需要实际硬编码你正在寻找的特定映射,从字符串文字到字符串文字:
type SomeMoreDataMapping = {
prop1: "prop1Change"
prop2: "prop2Change"
}
有了这个映射,你可以定义这些:
type ValueOf = T[keyof T]
type KeyValueTupleToObject = {
[K in T[0]]: Extract[1]
}
type MapKeys> =
KeyValueTupleToObject
[K in keyof T]: [K extends keyof M ? M[K] : K, T[K]]
}>>
简要介绍:
> ValueOf< T>只返回类型T的属性值类型的并集.
> KeyValueTupleToObject采用这样的元组类型的并集:[“a”,string] | [“b”,number]并将它们转换为如下对象类型:{a:string,b:number}.
>和MapKeys< T,M>采用类型T和键映射M并用M中的相应键替换M中存在的T中的任何键.如果M中的键不存在,则不转换键.如果T中的密钥不存在于T中,则将被忽略.
现在你可以(最后)这样做:
type SomeMoreData= MapKeys;
如果您检查SomeMoreData,您会看到它具有正确的类型:
var someMoreData: SomeMoreData = {
prop1Change: 'Mystery Science Theater',
prop2Change: 3000
} // type checks
这应该可以让你做一些有趣的事情,如:
function makeTheChange(input: T): MapKeys {
var ret = {} as MapKeys;
for (var k in input) {
// lots of any needed here; hard to convince the type system you're doing the right thing
var nk: keyof typeof ret = ((k === 'prop1') ? 'prop1Change' : (k === 'prop2') ? 'prop2Change' : k);
ret[nk] = input[k];
}
return ret;
}
var changed = makeTheChange({ prop1: 'Gypsy', prop2: 'Tom', prop3: 'Crow' });
console.log(changed.prop1Change.charAt(0)); //ok
console.log(changed.prop2Change.charAt(0)); //ok
console.log(changed.prop3.charAt(0)); //ok
希望有所帮助.祝好运!
更新于2018年9月,以利用TS 2.8引入的conditional types优势