-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
BugA bug in TypeScriptA bug in TypeScript
Milestone
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.
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScript