您可以在对象上强制执行键,但让打字稿推断出Value的类型吗?

时间:2019-06-17 18:16:18

标签: typescript typescript3.0

我正在尝试创建一个要在其中强制执行键的对象,但很高兴让打字稿推断出值的类型。 一个简单的例子是

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') }
}

TSPlayground

这可能吗?

1 个答案:

答案 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

您会收到有关键缺失的警告,并且它不会忘记值类型。希望能有所帮助;祝你好运!

Link to code


更新:助手功能可能会禁用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

Link to code

祝你好运!