3
  function test(data){
      console.log(data)
  }

  test({comments: 'hi', eat: true, sleep: true})

In the test function, I am sure of the comment argument will appear, where as for other arguments, the properties might be dynamic but the value will be of boolean type,

  test({comments: 'hi', drink: true, sleep: true})

considering this situation, how should I correctly type data? I have tried something like this, but it seems wrong

function(data: {data: {comments: string, [key: string]: boolean})
sridhar..
  • 1,945
  • 15
  • 19
  • Yes. i just want to console. Edited the question – sridhar.. Nov 26 '20 at 09:42
  • Is the question, then, "what type do I give to the parameter `data`, which should be an object with at least one property named `comments` of type string, but which could have lots of other properties that I don't care about"? – Ray Toal Nov 26 '20 at 09:43
  • Yes.. I dont care about other properties.. – sridhar.. Nov 26 '20 at 09:45
  • If you don't care about the other properties, then `type DataType = { comments: string; [key: string]: unknown; };` will work. Ref: https://stackoverflow.com/a/33860616 – Yoshi Nov 26 '20 at 09:50
  • Sorry about the above comment. I know that other properties value would be boolean – sridhar.. Nov 26 '20 at 09:53
  • Ah good, then it is not the same as this question? https://stackoverflow.com/a/42724170/831878 Because you want to restrict all the other properties to boolean? – Ray Toal Nov 26 '20 at 09:54
  • That solution doesn't seem to work, as soon as i keep boolean, vs code editor is throwing errors – sridhar.. Nov 26 '20 at 09:58
  • 1
    Right, right, your question is indeed different (and pretty cool). Looks like intersection types have potential, but fall short. More info here: https://github.com/microsoft/TypeScript/issues/20597. – Ray Toal Nov 26 '20 at 10:05
  • Relevant issue https://github.com/microsoft/TypeScript/issues/17867 – Aleksey L. Nov 26 '20 at 12:40

1 Answers1

1

I can suggest you some kind of workaround:

function test<T extends {
  [key: string]: any;
}>(data: { comments: unknown } & { [key in keyof T]: key extends "comments" ? string : boolean }) {
  const comments = data.comments as string;
  console.log(comments);
  console.log(data.eat);
  console.log(data.sleep);
}

test({comments: "hi"}); // works
test({comments: "hi", eat: true}); // works
test({comments: true}); // doesn't works
test({comments: 5}); // doesn't works
test({comments: "hi", eat: "true"}); // doesn't works
test({comments: "hi", eat: 5}); // doesn't works

It typed well outside of the function's body, but in function's body to type data.comments correctly you should add some narrowing.