or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# @mui/types

1

2

@mui/types provides essential TypeScript utility types and interfaces specifically designed for Material UI components and the broader React ecosystem. It includes advanced type manipulation utilities, overridable component interfaces, prop injection patterns, and string union generation helpers that enable robust type safety and component composition patterns.

3

4

## Package Information

5

6

- **Package Name**: @mui/types

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @mui/types`

10

11

## Core Imports

12

13

```typescript

14

import {

15

DistributiveOmit,

16

OverridableComponent,

17

OverridableTypeMap,

18

PropInjector,

19

Simplify,

20

expectType

21

} from "@mui/types";

22

```

23

24

For CommonJS:

25

26

```javascript

27

const {

28

DistributiveOmit,

29

OverridableComponent,

30

PropInjector

31

} = require("@mui/types");

32

```

33

34

## Basic Usage

35

36

```typescript

37

import {

38

OverridableComponent,

39

OverridableTypeMap,

40

DistributiveOmit,

41

Simplify

42

} from "@mui/types";

43

44

// Define a component with overridable root element

45

interface ButtonTypeMap extends OverridableTypeMap {

46

props: {

47

variant?: "contained" | "outlined" | "text";

48

disabled?: boolean;

49

};

50

defaultComponent: "button";

51

}

52

53

// Create an overridable component type

54

const Button: OverridableComponent<ButtonTypeMap> = {} as any;

55

56

// Usage with default component (button)

57

<Button variant="contained" disabled onClick={() => {}} />

58

59

// Usage with custom component (a)

60

<Button component="a" href="/home" variant="outlined" />

61

62

// Type utilities

63

type CleanProps = DistributiveOmit<{ a: string; b: number; c: boolean }, "b" | "c">;

64

// Result: { a: string }

65

66

type SimpleType = Simplify<{ a: string } & { b: number }>;

67

// Result: { a: string; b: number }

68

```

69

70

## Architecture

71

72

@mui/types is built around several key patterns:

73

74

- **Component Polymorphism**: The `component` prop pattern allowing flexible component composition

75

- **Type Safety**: Advanced TypeScript utilities for maintaining strict typing during composition

76

- **Prop Injection**: Higher-order component patterns with type-safe prop manipulation

77

- **Distributive Operations**: Type utilities that work correctly with union types

78

- **Testing Utilities**: Type-level testing and validation helpers

79

80

## Capabilities

81

82

### Type Manipulation Utilities

83

84

Core TypeScript utilities for advanced type operations and manipulation.

85

86

```typescript { .api }

87

/**

88

* Remove properties K from T, distributive for union types

89

*/

90

type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;

91

92

/**

93

* Like T & U, but using value types from U where properties overlap

94

*/

95

type Overwrite<T, U> = DistributiveOmit<T, keyof U> & U;

96

97

/**

98

* Simplifies display of a type without modifying it

99

*/

100

type Simplify<T> = T extends Function ? T : { [K in keyof T]: T[K] };

101

102

/**

103

* Changes properties K from T to required

104

*/

105

type PartiallyRequired<T, K extends keyof T> = DistributiveOmit<T, K> & {

106

[P in K]-?: T[P];

107

};

108

109

/**

110

* Generate string literal types with default record T and override record U

111

*/

112

type OverridableStringUnion<T extends string | number, U = {}> = GenerateStringUnion<

113

Overwrite<Record<T, true>, U>

114

>;

115

```

116

117

### Component Polymorphism

118

119

Advanced component patterns enabling the `component` prop for flexible component composition.

120

121

```typescript { .api }

122

/**

123

* A component whose root component can be controlled via a component prop

124

*/

125

interface OverridableComponent<M extends OverridableTypeMap> {

126

<C extends React.ElementType>(

127

props: {

128

/**

129

* The component used for the root node.

130

* Either a string to use a HTML element or a component.

131

*/

132

component: C;

133

} & OverrideProps<M, C>,

134

): React.JSX.Element | null;

135

(props: DefaultComponentProps<M>): React.JSX.Element | null;

136

propTypes?: any;

137

}

138

139

/**

140

* Base interface for overridable component type mapping

141

*/

142

interface OverridableTypeMap {

143

props: {};

144

defaultComponent: React.ElementType;

145

}

146

147

/**

148

* Props when component={Component} is used

149

*/

150

type OverrideProps<

151

M extends OverridableTypeMap,

152

C extends React.ElementType

153

> = (

154

& BaseProps<M>

155

& DistributiveOmit<React.ComponentPropsWithRef<C>, keyof BaseProps<M>>

156

);

157

158

/**

159

* Props when component={Component} is NOT used

160

*/

161

type DefaultComponentProps<M extends OverridableTypeMap> =

162

& BaseProps<M>

163

& DistributiveOmit<React.ComponentPropsWithRef<M['defaultComponent']>, keyof BaseProps<M>>;

164

165

/**

166

* Props defined on the component from the type map

167

*/

168

type BaseProps<M extends OverridableTypeMap> = M['props'];

169

```

170

171

### Prop Injection Patterns

172

173

Higher-order component utilities for type-safe prop injection and manipulation.

174

175

```typescript { .api }

176

/**

177

* Ensures overlapping properties between T and U have non-conflicting value types

178

*/

179

type ConsistentWith<DecorationTargetProps, InjectedProps> = {

180

[P in keyof DecorationTargetProps]: P extends keyof InjectedProps

181

? InjectedProps[P] extends DecorationTargetProps[P]

182

? DecorationTargetProps[P]

183

: InjectedProps[P]

184

: DecorationTargetProps[P];

185

};

186

187

/**

188

* A function that takes {component} and returns a component that passes along

189

* all props to {component} except the {InjectedProps} and accepts additional {AdditionalProps}

190

*/

191

type PropInjector<InjectedProps, AdditionalProps = {}> = <

192

C extends React.JSXElementConstructor<ConsistentWith<React.ComponentProps<C>, InjectedProps>>,

193

>(

194

component: C,

195

) => React.JSXElementConstructor<

196

DistributiveOmit<

197

React.JSX.LibraryManagedAttributes<C, React.ComponentProps<C>>,

198

keyof InjectedProps

199

> &

200

AdditionalProps

201

>;

202

```

203

204

### Type Testing Utilities

205

206

Tools for type-level testing and validation in TypeScript projects.

207

208

```typescript { .api }

209

/**

210

* Conditional type for exact type equality checking

211

*/

212

type IfEquals<T, U, Y = unknown, N = never> =

213

(<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? Y : N;

214

215

/**

216

* Issues a type error if Expected is not identical to Actual

217

* @param actual - Value to test, should be typeof value statement

218

*/

219

declare function expectType<Expected, Actual>(

220

actual: IfEquals<Actual, Expected, Actual>,

221

): void;

222

```

223

224

## Usage Examples

225

226

### Creating Overridable Components

227

228

```typescript

229

import { OverridableComponent, OverridableTypeMap } from "@mui/types";

230

231

// Define your component's type map

232

interface MyComponentTypeMap extends OverridableTypeMap {

233

props: {

234

color?: "primary" | "secondary";

235

size?: "small" | "medium" | "large";

236

};

237

defaultComponent: "div";

238

}

239

240

// Use the type in your component definition

241

const MyComponent: OverridableComponent<MyComponentTypeMap> =

242

React.forwardRef((props, ref) => {

243

const { component: Component = "div", color, size, ...other } = props;

244

return <Component ref={ref} {...other} />;

245

});

246

247

// Usage

248

<MyComponent color="primary" /> // renders as div

249

<MyComponent component="section" color="secondary" /> // renders as section

250

<MyComponent component="a" href="/link" color="primary" /> // renders as anchor with href

251

```

252

253

### Higher-Order Component with Prop Injection

254

255

```typescript

256

import { PropInjector, ConsistentWith } from "@mui/types";

257

258

interface ThemeProps {

259

theme: {

260

primaryColor: string;

261

backgroundColor: string;

262

};

263

}

264

265

// Create a HOC that injects theme props

266

const withTheme: PropInjector<ThemeProps> = (Component) => {

267

return (props) => {

268

const theme = {

269

primaryColor: "#1976d2",

270

backgroundColor: "#ffffff",

271

};

272

return <Component {...props} theme={theme} />;

273

};

274

};

275

276

// Use with any component

277

const MyButton = (props: { label: string; theme: ThemeProps["theme"] }) => (

278

<button style={{ color: props.theme.primaryColor }}>

279

{props.label}

280

</button>

281

);

282

283

const ThemedButton = withTheme(MyButton);

284

// Usage: <ThemedButton label="Click me" /> (theme is automatically injected)

285

```

286

287

### Type Manipulation

288

289

```typescript

290

import { DistributiveOmit, Overwrite, Simplify, PartiallyRequired } from "@mui/types";

291

292

interface User {

293

id: number;

294

name: string;

295

email: string;

296

isActive: boolean;

297

}

298

299

// Remove sensitive fields for public API

300

type PublicUser = DistributiveOmit<User, "email" | "isActive">;

301

// Result: { id: number; name: string }

302

303

// Override specific properties

304

type UserWithStringId = Overwrite<User, { id: string }>;

305

// Result: { id: string; name: string; email: string; isActive: boolean }

306

307

// Simplify complex intersection types

308

type ComplexType = { a: string } & { b: number } & { c: boolean };

309

type SimpleType = Simplify<ComplexType>;

310

// Result: { a: string; b: number; c: boolean }

311

312

// Make specific properties required

313

type UserWithRequiredEmail = PartiallyRequired<Partial<User>, "email">;

314

// Result: { id?: number; name?: string; email: string; isActive?: boolean }

315

```

316

317

### Type Testing

318

319

```typescript

320

import { expectType, IfEquals } from "@mui/types";

321

322

// Test exact type equality

323

const value = "hello";

324

expectType<string, typeof value>(value); // ✓ passes

325

// expectType<number, typeof value>(value); // ✗ type error

326

327

// Conditional type checking

328

type IsString<T> = IfEquals<T, string, "yes", "no">;

329

type Test1 = IsString<string>; // "yes"

330

type Test2 = IsString<number>; // "no"

331

```