When passing a conditional statement to the variant
prop of the TextField component like this:
<TextField
variant={isLongTextQuestion ? "outlined" : "standard"}
...
/>
I get a typescript error saying:
Types of property 'variant' are incompatible.
Type '"standard" | "outlined"' is not assignable to type '"outlined"'.
Type '"standard"' is not assignable to type '"outlined"'.ts(2322)
TextField
component should allow this statement as it accepts both outlined
and standard
independently.
Gives typescript type error
Link:
https://codesandbox.io/s/mor0mrooz9
| Tech | Version |
|--------------|---------|
| Material-UI | v3.9.3 |
| React | v16.8.4 |
| Browser | |
| TypeScript | |
| etc. | |
Looks more like how Typescript work and not material-ui issue itself... https://github.com/Microsoft/TypeScript/issues/16870
This is a limitation in TypeScript. Basically { type: 'bird' | 'fish' } is not assignable to { type: 'bird' } | { type: 'fish' }
. See microsoft/TypeScript#8289.
I don't know of any sound solution without runtime overhead. Until then maybe
function App({ isLongTextQuestion }: { isLongTextQuestion: boolean }) {
const variantProps = isLongTextQuestion
? // or use const expression
{ variant: "outlined" as "outlined" }
: { variant: "standard" as "standard" };
const props: StandardTextFieldProps | OutlinedTextFieldProps = {
id: "test",
type: "text",
value: "abc",
rows: 3,
multiline: isLongTextQuestion,
...variantProps
};
return <TextField {...props} />;
}
works for you?
Ah, I see. That'll work @eps1lon, thanks a lot!
I'm running into the same issue and I'm not sure how to fix it with your above workaround.
Basic example (I know the example doesn't make contextual sense but basically all I'm doing is extending the default TextInput component):
interface MyTextInputProps extends BaseTextFieldProps {
readonly foo: number;
}
const MyTextInput: FC<MyTextInputProps> = ({ foo, ...props }) => {
const newLabel = foo.toString();
return <TextInput label={newLabel} {...props} />;
}
How would I fix this? Are there any plans to update MUI so that the BaseTextFieldProps work properly?
I figured out a workaround. For anyone else who sees this, try this:
interface MyTextInputProps extends BaseTextFieldProps {
readonly foo: number;
}
const MyTextInput: FC<MyTextInputProps> = ({ foo, ...props }) => {
const newLabel = foo.toString();
/**
* Hack to make 'props.variant' type safe
*
* See: https://github.com/mui-org/material-ui/issues/15697
*/
const tsProps = (() => {
let tsVariant;
switch (variant) {
case "outlined": {
tsVariant = { variant: variant as "outlined" };
break;
}
case "filled": {
tsVariant = { variant: "filled" as "filled" };
break;
}
case "standard":
default: {
tsVariant = { variant: "standard" as "standard" };
break;
}
}
const p = props;
delete p.variant;
return { ...p, ...tsVariant };
})();
return <TextInput label={newLabel} {...tsProps} />;
}
It's far from ideal though as the only purpose of this entire function is to fix the props.variant
bug.
Thanks a lot @TidyIQ!
Hi guys I found this issue as well.. quite frustrating bug :-) thanks for the solution.
this must be joke, so resolution is importing this helper anywhere its needed ?
fuck dat and do this:
<TextField variant={control.textFieldVariant as any} />
I had react error when tried as any
from previous answer
My way
class TextViewVariety {
static FILLED = 'filled' as 'filled'
static OUTLINED = 'outlined' as 'outlined'
}
...
variant={ this.props.variety as any }
It works well
Most helpful comment
I figured out a workaround. For anyone else who sees this, try this:
It's far from ideal though as the only purpose of this entire function is to fix the
props.variant
bug.