根据键类型的特定值,使第二个参数变为可选。

huangapple go评论64阅读模式
英文:

Making second parameter optional based on specific value of a key type

问题

I have code like

interface MY_TYPES {
  'xyz': string;
  'abc': number;
  'baz': undefined;
}

function testIt<T extends keyof MY_TYPES>(key: T, value?: MY_TYPES[T]) {
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt('xyz', 123); // error
testIt('xyz'); // NO ERROR BY TS, but it should show error
testIt('xyz', 'str'); // good
testIt('baz'); // good
testIt('baz', 3); // error

In case of testIt('xyz'), it's showing no error, but I want TypeScript to complain in such cases because MY_TYPES has some value for this key. However, TypeScript is not complaining here.

playground

英文:

I have code like

interface MY_TYPES {
  &#39;xyz&#39;: string;
  &#39;abc&#39;: number;
  &#39;baz&#39;: undefined;
}

function testIt&lt;T extends keyof MY_TYPES&gt;(key: T, value?: MY_TYPES[T]) {
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt(&#39;xyz&#39;, 123); // error
testIt(&#39;xyz&#39;); // NO ERROR BY TS, but it should show error
testIt(&#39;xyz&#39;, &#39;str&#39;); // good
testIt(&#39;baz&#39;); // good
testIt(&#39;baz&#39;, 3); // error

In case of testIt(&#39;xyz&#39;) Its showing no error, but I want TS to complain on such cases as MY_TYPES has some value for this key.
But TS is complaining here. playground

答案1

得分: 2

你可以使用rest parameter 并有条件地对参数元组进行类型化:

interface MY_TYPES {
  'xyz': string;
  'abc': number;
  'baz': undefined;
}

function testIt<T extends keyof MY_TYPES>(
  ...args: MY_TYPES[T] extends undefined ? [T] : [T, MY_TYPES[T]]
) {
  const [key, value] = args;
  
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt('xyz'); // error
testIt('xyz', 123); // error
testIt('xyz', 'str'); // correct
testIt('baz'); // correct
testIt('baz', 3); // error
英文:

You could use a rest parameter and conditionally type the parameter tuple:

interface MY_TYPES {
  &#39;xyz&#39;: string;
  &#39;abc&#39;: number;
  &#39;baz&#39;: undefined;
}

function testIt&lt;T extends keyof MY_TYPES&gt;(
  ...args: MY_TYPES[T] extends undefined ? [T] : [T, MY_TYPES[T]]
) {
  const [key, value] = args;
  
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt(&#39;xyz&#39;); // error
testIt(&#39;xyz&#39;, 123); // error
testIt(&#39;xyz&#39;, &#39;str&#39;); // correct
testIt(&#39;baz&#39;); // correct
testIt(&#39;baz&#39;, 3); // error

答案2

得分: 0

只需添加函数重载以提供可能的类型:

interface MY_TYPES {
  'xyz': string;
  'abc': number;
  'baz': undefined;
}
function testIt(key: 'xyz', value: string): undefined
function testIt(key: 'abc', value: number): undefined
function testIt(key: 'baz'): undefined

function testIt<T extends keyof MY_TYPES>(key: T, value?: MY_TYPES[T]) {
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt('xyz', 123); // 错误
testIt('xyz');
testIt('xyz', 'str'); // 正确
testIt('baz'); // 正确
testIt('baz', 3); // 错误

Playground

英文:

Just add function overloading to give possible types:

interface MY_TYPES {
  &#39;xyz&#39;: string;
  &#39;abc&#39;: number;
  &#39;baz&#39;: undefined;
}
function testIt(key: &#39;xyz&#39;, value: string) : undefined
function testIt(key: &#39;abc&#39;, value: number) : undefined
function testIt(key: &#39;baz&#39;) : undefined


function testIt&lt;T extends keyof MY_TYPES&gt;(key: T, value?: MY_TYPES[T]) {
  console.log(key);

  if (value) {
    console.log(value);
  }
}

testIt(&#39;xyz&#39;, 123); // error
testIt(&#39;xyz&#39;);
testIt(&#39;xyz&#39;, &#39;str&#39;); // correct
testIt(&#39;baz&#39;); // correct
testIt(&#39;baz&#39;, 3); // error


Playground

huangapple
  • 本文由 发表于 2023年3月7日 13:58:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定