Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
474 views
in Technique[技术] by (71.8m points)

typescript - Narrow down type of callback Parameter

I have a function:

type Callback = (data: Record<string, unknown>) => void
const execCb = (cb: Callback) => {
  cb(somedata)
}

As you can see, data is pretty generic because it could be any object. However, when I define my callbacks, I would like to narrow down the data to specific types:

type MyCallBackData = {
  foo: string,
  bar: number
}
const myCallback = (data: MyCallBackData) => {
  // do something
}

execCb(myCallback)

Typescript complains, that Type 'Record<string, unknown>' is missing the following properties from type 'MyCallBackData': foo, bar

How can I properly narrow down a type in this case?

Plaground: Link

question from:https://stackoverflow.com/questions/65843307/narrow-down-type-of-callback-parameter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The parameter Record<string, unknown>, means you can pass in a object with no properties (like you do, where you pass {}) but the callback you pass in requires proeprties on the first argument. So this is not type safe.

What you could do is make execCb generic, so the parameter can be any type. THis also means you won't be able to pass in a concrete object in execCb (at least not without a type assertion). You can for example pass it as an extra parameter to execCb.

type Callback<T> = (data: T) => void

const execCb = <T extends Record<string, unknown>>(cb: Callback<T>, param: T) => {
  cb(param)
}

type MyCallBackData = {
  foo: string,
  bar: number
}

const myCallback = (data: MyCallBackData) => {
  // do something
}

execCb(myCallback, {
  foo: "",
  bar: 1
})

Playground Link


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...