您能否在对象上强制执行键,但让typescript推断值的类型?

您能否在对象上强制执行键,但让typescript推断值的类型?,typescript,typescript3.0,Typescript,Typescript3.0,我正在尝试创建一个对象,我希望在其中强制执行键,但很乐意让typescript推断值的类型。 一个简单的例子是 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

我正在尝试创建一个对象,我希望在其中强制执行键,但很乐意让typescript推断值的类型。 一个简单的例子是

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


这可能吗?

我建议使用一个通用的助手函数,该函数将其输入限制为
JustKeysOfFooVals
的子类型,并且只返回其输入,而不扩大其范围:

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


更新:助手功能可能会禁用。如果您需要这些(而且您可能不需要,毕竟值
{a:“a”,b:“b”}
是类型
{a:string}
的完全有效实例),那么您可以使用另一个通用约束来模拟:

类型精确=T&Record;
常数justKeysOfFooVals=(t:t)=>t;
const foo3Vals=justKeysOfFooVals({
a:'字符串',
b:10,
c:Promise.resolve('string'),
e:()=>{console.log('bar')},
f:1//错误!
}); // 数字不能分配给从不


祝你好运

未知类型在这里可能很方便,使所有类型都未知。是的,看起来这是唯一的方法,尽管应该有另一种方法。这将引发一个问题
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
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