Issue
I copied the following from the AWS Amplify tutorial:
const styles = {
container: { flexDirection: 'column' },
...
};
<div style={styles.container}>
But I'm getting:
Type '{ flexDirection: string; }' is not assignable to type 'CSSProperties'.
Types of property 'flexDirection' are incompatible.
Type 'string' is not assignable to type '"column" | "inherit" | "-moz-initial" | "initial" | "revert" | "unset" | "column-reverse" | "row" | "row-reverse" | undefined'.
I can easily work around this by placing the style inline, but I'm curious why TypeScript is considering this an error. This is a pretty basic example and I'm surprised TS is failing on it, so it makes me wary about using TS.
Solution
Here is a TS Playground illustrating the problem and four possible solutions:
type FlexDirection = "column" | "inherit" | "-moz-initial" | "initial" | "revert" | "unset" | "column-reverse" | "row" | "row-reverse" | undefined;
type Styles = {
container: {
flexDirection: FlexDirection
}
}
function doStuff(a: Styles) { }
const stylesDoesNotWork = {
container: { flexDirection: 'column' }
};
const stylesWithCast = {
container: { flexDirection: 'column' as 'column' }
}
const stylesFieldConst = {
container: { flexDirection: 'column' } as const
};
const stylesConst = {
container: { flexDirection: 'column' }
} as const;
doStuff(stylesDoesNotWork);
doStuff(stylesWithCast);
doStuff(stylesFieldConst);
doStuff(stylesConst);
By default, TypeScript is going to infer a type string for the object you are declaring. You might be mutating it somewhere and changing the value, in which case the literal type would not be correct. So the basic options to fix it are to:
- Manually annotate the variable so TypeScript doesn't infer string.
- Add
as 'column'cast to tell TypeScript to use the literal type. - Use
as conston either the field or entire object to tell TypeScript that field is not allowed to be changed, which allows Typescript to infer the literal value.
Answered By - TLadd
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.