If I have an object like this:
type GA = {
name: 'GameA',
duration: number
}
type GB = {
name: 'GameB',
duration: number
}
type Game = GA | GB;
type Initial<G extends Game = Game> = Pick<G, 'name'>
const Games = {
GameA: {
create: (initial: Initial<GA>): GA => {
throw new Error('not implemented')
}
},
GameB: {
create: (initial: Initial<GB>): GB => {
throw new Error('not implemented')
}
},
}
When trying to invoke the create
of either by using an object with name
, (property) name: "GameA" | "GameB"
(property) name: "GameA" | "GameB"
like this:
const game = Games[objectWithName.name].create(objectWithName)
reports an error:
Argument of type 'Game' is not assignable to parameter of type 'never'.
The intersection 'Pick<GA, "name" | "duration"> & Pick<GB, "name" | "duration">' was reduced to 'never' because property 'name' has conflicting types in some constituents.
Type 'GA' is not assignable to type 'never'.(2345)
How can I properly type my Games
object or the objectWithName
, so that the parameters aren't reduced to 'never'?
This typescript playground minimal repro of the issue makes it clear that an Initial<GameA>
can't be assigned to a GameA
, given the Pick has eliminated some of the required fields.
This is the origin of your problem. This is also demonstrated by goodGame
where using a valid GameA object as a 'prototype' DOESN'T face an issue in the create call.
type GA = {
name: 'GameA',
duration: number
}
type GB = {
name: 'GameB',
duration: number
}
type Game = GA | GB;
type Initial<G extends Game = Game> = Pick<G, 'name'>
const Games = {
GameA: {
create: (initial: Initial<GA>): GA => {
throw new Error('not implemented')
}
},
GameB: {
create: (initial: Initial<GB>): GB => {
throw new Error('not implemented')
}
},
}
const gameA : Game = {
name:"GameA",
duration:100
}
const initialGameA : Initial<Game> = {
name:"GameA",
}
const goodGame = Games[gameA.name].create(gameA)
const badGame = Games[initialGameA.name].create(initialGameA)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.