Closed
Description
TypeScript Version: 3.6.3
Search Terms:
array.map, expression is not callable, union type signatures,
Code
The following code is the exact same code as in this codesandbox
https://codesandbox.io/s/lingering-sun-7itgj
interface Product_result {
__typename: 'Product'
id: number
description: string | null
}
interface Campaign_result {
__typename: 'Campaign'
id: number
products: (Product_result | null)[] | null
}
interface Product {
id: number
description: string
specific: boolean
}
interface Campaign {
products: Product[]
}
type CompoundType = Campaign_result | Campaign
/* --- */
const props: { campaign?: Campaign_result } = {}
const emptyCampaign: Campaign = {
products: []
}
const initialData: CompoundType = props.campaign || emptyCampaign
/*
Cannot invoke an expression whose type lacks a call signature. Type '
(<U>(callbackfn: (value: Product_result, index: number, array: Product_result[]) => U, thisArg?: any) => U[])
| (<U>(callbackfn: (value: Product, index: number, array: Product[]) => U, thisArg?: any) => U[])
' has no compatible call signatures.
product inside map is any, but I know `id` is there
*/
initialData.products.map(product => product.id)
// product is { description: string, id: number } - as expected
const product = initialData.products[0]
// product inside map is { description: string, id: number } - as expected
;(initialData.products as Array<CompoundType['products'][0]>).map(product => product.id)
/* interestingly */
type T01 = Array<CompoundType['products'][0]> // T01: (Product_result | Product)[] - I can actually have mix of both. Products that were fetched and Products added via a Form
type T02 = CompoundType['products'] // T02: Product_result[] | Product[]
declare const v1: T01
v1.map(product => product) // OK
declare const v2: T02
v2.map(product => product) // NOK
Expected behavior:
I know id
is there, so this should work
initialData.products.map(product => product.id)
This workaround works
(initialData.products as Array<CompoundType['products'][0]>).map(product => product.id)
Actual behavior:
The map gives a non compatible call signature error (as in the snippet above), and the product inside is any.
Related
TypeScript 3.3 - Improved behavior for calling union types
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-3.html#caveats