Varför kan inte { loading: { a: false } } tilldelas till en parameter av typen Partial<Factory<T>> i TypeScript?
Jag har följande TypeScript-kod:
type Factory<T> = T & {
loading: {
[K: string]: boolean
}
}
function factoryInitState<T>(initState: T) {
const setFn = (state: Partial<Factory<T>>) => {}
// Argument of type '{ loading: { a: false; }; }' is not assignable to parameter of type 'Partial<Factory<T>>'.
setFn({
loading: {
a: false,
},
})
}
Kan någon förklara varför detta fel uppstår och hur man åtgärdar det.
Här är förslaget från GPT,
type Factory<T> = {
[K in keyof T]: T[K]
} & {
loading: {
[K: string]: boolean
}
}
function factoryInitState<T>(initState: T) {
const setFn = (state: Partial<Factory<T>>) => {}
setFn({
loading: {
a: false,
},
} as unknown as Partial<Factory<T>>)
}
factoryInitState({})
Men det är inte elegant
Svar #1
Du måste sprida initState på Factory<T> för att uppfylla T-gränsen själv:
type Factory<T> = T & {
loading: {
[K: string]: boolean
}
}
function factoryInitState<T>(initState: T) {
const setFn = (state: Partial<Factory<T>>) => {}
// Argument of type '{ loading: { a: false; }; }' is not assignable to parameter of type 'Partial<Factory<T>>'.
setFn({
...initState,
loading: {
a: false,
},
})
}
Svar #2
Jag tror att detta är en begränsning i kompilatorn, även om jag inte kan precis peka ut det (troligtvis beroende på hur Partial är definierad).
Så länge den generiska T är okänd, kommer Partial<T> (eller, i ditt fall, Partial<Factory<T>>) inte vara kompatibel med ett objekt som inte har några kända egenskaper gemensamma med T (det vill fortfarande veta vilka dessa egenskaper är).
Det finns dock ett enkelt sätt att kringgå det:
type Factory<T> = T & {
loading: {
[K: string]: boolean
}
}
function factoryInitState<T>(initState: T) {
const setFn = (state: Partial<Factory<T>>) => {}
setFn({
...({} as T),
loading: {
a: false,
},
})
}
