我正在尝试创建一个要在其中强制执行键的对象,但很高兴让打字稿推断出值的类型。 一个简单的例子是
const fooVals = {
a: null,
b: null,
c: null,
e: null,
}
type TfooVals = typeof fooVals
type JustKeysOfFooVals = { [key in keyof TfooVals]: any};
// TS deduces correct types of foo1Vals but does not let me know e is missing
const foo1Vals = {
a: 'string',
b: 10,
c: Promise.resolve('string') ,
// e: () => { console.log('bar') }
}
// lets me know 'e' is missing, but makes types any
const foo2Vals: JustKeysOfFooVals = {
a: 'string',
b: 10,
c: Promise.resolve('string') ,
e: () => { console.log('bar') }
}
这可能吗?
答案 0 :(得分:1)
我建议使用通用辅助函数,该函数将其输入限制为JustKeysOfFooVals
的子类型,并仅返回其输入而不会扩大:>
const justKeysOfFooVals = <T extends JustKeysOfFooVals>(t: T)=>t;
然后您将像这样使用它:
const foo1Vals = justKeysOfFooVals({
a: 'string',
b: 10,
c: Promise.resolve('string') ,
// e: () => { console.log('bar') }
}); // error! property 'e' is missing
const foo2Vals = justKeysOfFooVals({
a: 'string',
b: 10,
c: Promise.resolve('string') ,
e: () => { console.log('bar') }
}); // okay
foo2Vals.e(); // okay
您会收到有关键缺失的警告,并且它不会忘记值类型。希望能有所帮助;祝你好运!
更新:助手功能可能会禁用excess property checks。如果需要这些参数(并且可能不需要,毕竟值{a: "a", b: "b"}
是类型{a: string}
的完全有效的实例),则可以使用另一个通用约束来模拟exact types:>
type Exactly<T, U> = T & Record<Exclude<keyof U, keyof T>, never>;
const justKeysOfFooVals = <T extends Exactly<JustKeysOfFooVals, T>>(t: T)=>t;
const foo3Vals = justKeysOfFooVals({
a: 'string',
b: 10,
c: Promise.resolve('string') ,
e: () => { console.log('bar') },
f: 1 // error!
}); // number is not assignable to never
祝你好运!