-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object literal expanded to the wrong union type arm #22019
Comments
I reduced this issue a lot. test.ts: import { StyleProp, ViewStyle, RecursiveArray, RegisteredStyle } from 'react-native'
const screen: ViewStyle = {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
let x: StyleProp<ViewStyle> = screen Here are the definitions of interface RecursiveArray<T> extends Array<T | RecursiveArray<T>> {}
export type StyleProp<T> = T | RegisteredStyle<T> | RecursiveArray<T | RegisteredStyle<T> | Falsy> | Falsy```; test.ts compiles with no error, because However, if I simply remove the type hint from import { StyleProp, ViewStyle } from 'react-native'
const screen = {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
let x: StyleProp<ViewStyle> = screen then tsc outputs the following on the src/bug.tsx(9,5): error TS2322: Type '{ flex: number; justifyContent: string; alignItems: string; }' is not assignable to type 'StyleProp<ViewStyle>'.
Type '{ flex: number; justifyContent: string; alignItems: string; }' is not assignable to type 'RecursiveArray<false | ViewStyle | RegisteredStyle<ViewStyle> | null | undefined>'.
Property '[Symbol.unscopables]' is missing in type '{ flex: number; justifyContent: string; alignItems: string; }'. To me, it seems that the main issue is that tsc is wrongly expanding |
What resolved this issue? |
@Rovanion Sorry, I should've explained the solution before closing the issue. TLDR: Use React Native's import { StyleSheet } from 'react-native'
const screen = StyleSheet.create({
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}) Long answer: const x = 'literal'
const y = {
x: 'literal'
} If you check the types, If you assign y to an interface expecting a literal string type, you get an error: interface A {
x: 'literal'
}
const y = {
x: 'literal'
}
let a: A = y <-- tsc error: "Type string is not assignable to type literal" OK, this is a bit unexpected but it's understandable. The problem happens when you use a union type: interface A {
x: 'literal'
}
const y = {
x: 'literal'
}
type B = A | number[]
let a: B = y <-- tsc error: "Property 'length' is missing in type { x: string }" The React Native bug in the original issue is an instance of this problem: interface ViewStyle {
...
justifyContent: 'center' | 'flex-end' | ...
...
} but the This is especially problematic for big libraries, as you get very long, non-intuitive error messages (you can see an example in the OP). It seems that this only happens for some union types.
|
TypeScript Version: 2.8.0-dev.20180217
Search Terms: "is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes", "Property '[Symbol.unscopables]' is missing in type"
Code
bug.tsx:
I also created a repository with the correct dependencies to make debugging this easier:
https://github.com/frankpf/tsc-react-native-bug
Expected behavior:
No error.
Actual behavior:
On the <View style={ screen }>, I get this error:
One super weird thing is that if I just pass the object literal, I get no error. So
<View style={ screen }>
errors, but this
<View style= { flex: 1, justifyContent: 'center', alignItems: 'center' }}>
does not.
If I remove the
justifyContent
andalignItems
properties from thescreen
variable:tsc also doesn't complain.
Related Issues: #15463 and #15419 may be slightly related
The text was updated successfully, but these errors were encountered: