typescript 如果函数arg作为泛型使用,TS将接受arg中的任何prop,如何限制?

a11xaf1n  于 2023-04-07  发布在  TypeScript
关注(0)|答案(2)|浏览(166)

我正在写一个函数,传递给它的对象的键在钩子的返回类型中使用:

type MyOptions = {
  [key: `${number}${'s'|'ms'}`]: string
}

function useMyHook<O extends MyOptions>(options: O): MyReturnType<O> {
  // ...
}

当调用这个函数时,typescript不会抱怨无效的键:

useMyHook({
  foo: 'bar'
})

如果我这样定义选项

const options: MyOptions = {
  foo: 'bar'
}

TypeScript将按预期突出显示无效键。
如何确保对函数参数进行正确的类型检查?
TSPlayground与代码

7ajki6be

7ajki6be1#

你可以检查O的键是否可以分配给MyOptions的键。如果可以,你给予options类型O。如果不可以,你可以使用MyOptions来触发额外的属性检查,就像你一直在写options: MyOptions一样。

function useMyHook<O extends MyOptions>(
    options: keyof O extends keyof MyOptions ? O : MyOptions
): MyReturnType<O> {
    return 42;
}

这将产生相同的错误:

useMyHook({
    foo: "bar", // Object literal may only specify known properties, and 'foo' does not exist in type 'MyOptions'.
});

const options: MyOptions = {
    foo: "bar", // Object literal may only specify known properties, and 'foo' does not exist in type 'MyOptions'.
};

同时仍然允许匹配MyOptions的对象:

useMyHook({
    "42ms": true, // okay
});

Playground

oxcyiej7

oxcyiej72#

你在找这样的东西吗?

type MyOptions = {
  name: string,
  subName: string
}

type MyReturnType<O> = {
    objectName: O;
}

function useMyHook<O extends MyOptions>(options: O): MyReturnType<O> {
  // do something...
  options.name = 'overwritename';

  const result: MyReturnType<O> = {
    objectName: options
  }

  return result;
}

const options: MyOptions = {
   name: 'foo',
   subName: 'bar'
};

const optionsError = {
   name: 'foo',
};

useMyHook({ name: 'foo', subName: 'bar' });
useMyHook(options);

useMyHook({ name: 'foo' }); // This will error in
useMyHook(optionsError); // This will error

TSPlayground

相关问题