Closed
Description
Bug Report
Full details in the playground link / below, summary:
export function setupImages<R extends ImageHolder<K>, K extends string>(item: R, keys: K[]): SetupImages<K> {
return <any>undefined
}
const test: TestInterface = <any>undefined
const two_steps = setupImages(test, ['image'])
const {prepare: prepare_two_steps, ...two_steps_rest} = two_steps
const {prepare: prepare_one_step, ...one_step_rest} = setupImages(test, ['image']) // Error on `test`
The two step version works, the one step version fails with
Argument of type 'TestInterface' is not assignable to parameter of type 'ImageHolder<string>'.
Type 'TestInterface' is not assignable to type 'ImageRefHolder<string>'.
Index signature for type '`${string}_ref`' is missing in type 'TestInterface'.(2345)
so apparently narrowing down K
fails.
🔎 Search Terms
Destructure, Destructuring assingment
🕗 Version & Regression Information
- This is the behavior in every version I tried (down to 4.5.5)
⏯ Playground Link
Playground link with relevant code
💻 Code
Tried to slim it down, but unfortunaely it's still a bit complex
export function setupImages<R extends ImageHolder<K>, K extends string>(item: R, keys: K[]): SetupImages<K> {
return <any>undefined
}
const test: TestInterface = <any>undefined
const two_steps = setupImages(test, ['image'])
const {prepare: prepare_two_steps, ...two_steps_rest} = two_steps
const {prepare: prepare_one_step, ...one_step_rest} = setupImages(test, ['image'])
/********
* Types
*/
export interface RouteRef {
uuid: string
}
export interface FileItem {
file: File
}
type ImageRefHolder<K extends string> = {
[P in `${K}_ref`]: RouteRef
}
type ImageUuidHolder<K extends string> = {
[P in `${K}_uuid`]: string
}
export type ImageHolder<K extends string> = ImageRefHolder<K> & ImageUuidHolder<K>
export type ImagesPrepared<I extends ImageHolder<K>, K extends string> = Omit<I, ImageOmitKeys<K>[number]> & ImageFinalHolder<K>
type ImageOmitKeys<K extends string> = (keyof ImageHolder<K>)[]
type ImageFinalFile<K extends string> = {
[P in K]?: File
}
type ImageFinalDelete<K extends string> = {
[P in `${K}__delete`]?: 1
}
type ImageFinalHolder<K extends string> = ImageFinalFile<K> & ImageFinalDelete<K>
type SetupImageRefsItem<K extends string> = {
[P in K]: FileItem
}
interface PrepareImages<K extends string> {
prepare: <R extends ImageHolder<K>>(data: R) => ImagesPrepared<R, K>
}
type SetupImageRefs<K extends string> = SetupImageRefsItem<K>
type SetupImages<K extends string> = SetupImageRefs<K> & PrepareImages<K>
export interface TestInterface {
name: string
image_ref: RouteRef
image_uuid: string
}
🙁 Actual behavior
Error on the indicated line
🙂 Expected behavior
No error as type resolution appears to work fine in the version with an intermediate variable. The one line version should imo be fully equivalent.