Skip to content

Commit dd1db39

Browse files
committed
Clarify that the rule applies to both local variables and instance properties, simplify examples
1 parent 5a39cdc commit dd1db39

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

README.md

+54-38
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,13 @@ _You can enable the following settings in Xcode by running [this script](resourc
340340
let sun = Star(mass: 1.989e30)
341341
let earth = Planet.earth
342342

343+
// NOT RECOMMENDED. However, since the linter doesn't have full type information, this is not enforced automatically.
344+
let moon: Moon = earth.moon // returns `Moon`
345+
346+
// RIGHT
347+
let moon = earth.moon
348+
let moon: PlanetaryBody? = earth.moon
349+
343350
// WRONG: Most literals provide a default type that can be inferred.
344351
let enableGravity: Bool = true
345352
let numberOfPlanets: Int = 8
@@ -369,70 +376,79 @@ _You can enable the following settings in Xcode by running [this script](resourc
369376

370377
</details>
371378

372-
* <a id='infer-property-types'></a>(<a href='#infer-property-types'>link</a>) **Prefer letting the type of a property be inferred from the right-hand-side value rather than writing the type explicitly on the left-hand side.** [![SwiftFormat: preferInferredTypes](https://img.shields.io/badge/SwiftFormat-preferInferredTypes-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#preferInferredTypes)
379+
* <a id='infer-property-types'></a>(<a href='#infer-property-types'>link</a>) **Prefer letting the type of a variable or property be inferred from the right-hand-side value rather than writing the type explicitly on the left-hand side.** [![SwiftFormat: preferInferredTypes](https://img.shields.io/badge/SwiftFormat-preferInferredTypes-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md#preferInferredTypes)
373380

374381
<details>
375382

383+
Prefer using inferred types when the right-hand-side value is a static member with a leading dot (e.g. an `init`, a `static` property / function, or an enum case). This applies to both local variables and property declarations:
384+
376385
```swift
377386
// WRONG
378-
let sun: Star = .init(mass: 1.989e30)
379-
let earth: Planet = .earth
387+
struct SolarSystemBuilder {
388+
let sun: Star = .init(mass: 1.989e30)
389+
let earth: Planet = .earth
380390

391+
func setUp() {
392+
let galaxy: Galaxy = .andromeda
393+
let system: SolarSystem = .init(sun, earth)
394+
galaxy.add(system)
395+
}
396+
}
397+
381398
// RIGHT
382-
let sun = Star(mass: 1.989e30)
383-
let earth = Planet.earth
399+
struct SolarSystemBuilder {
400+
let sun = Star(mass: 1.989e30)
401+
let earth = Planet.earth
384402

385-
// ALSO RIGHT: Explicit types are required when there is no right-hand-side value.
386-
let sun: Star
387-
let earth: Planet
388-
389-
// ALSO RIGHT: Explicit types can be necessary when the right-hand side has
390-
// a different type from the one written explicitly on the left-hand side.
391-
let naturalSatellite: PlanetaryBody? = Moon(mass: 7.347e22)
392-
let moon: PlanetaryBody? = nil // nil literals are typeless
393-
let numberOfPlanets: UInt = 8 // integer literals default to `Int`
394-
let sunMass: CGFloat = 1.989e30 // floating-point literals default to `Double`
395-
let planets: [Planet] = [] // empty collection literals are typeless
396-
397-
// ALSO RIGHT: Some of the examples above can also be written idiomatically without an explicit type on
398-
// the left-hand-side, by instead giving the right-hand side value an explicit type. Either style is fine.
399-
let numberOfPlanets = UInt(8)
400-
let sunMass = CGFloat(1.989e30)
401-
let planets = [Planet]()
403+
func setUp() {
404+
let galaxy = Galaxy.andromeda
405+
let system = SolarSystem(sun, earth)
406+
galaxy.add(system)
407+
}
408+
}
402409
```
403-
404-
There are some rarer cases where the inferred type syntax has a different meaning than the explicit type syntax. In these cases, the explicit type syntax is still permitted:
405-
410+
411+
Explicit types are still permitted in other cases:
412+
406413
```swift
407-
extension String {
408-
static let earth = "Earth"
409-
}
414+
// RIGHT: There is no right-hand-side value, so an explicit type is required.
415+
let sun: Star
410416

411-
// RIGHT: If the property's type is optional, moving the optional type
412-
// to the right-hand side may result in invalid code.
413-
let planetName: String? = .earth
414-
417+
// RIGHT: The right-hand-side is not a static member of the left-hand type.
418+
let moon: PlantaryBody = earth.moon
419+
let sunMass: Float = 1.989e30
420+
let planets: [Planet] = []
421+
let venusMoon: Moon? = nil
422+
```
423+
424+
There are some rare cases where the inferred type syntax has a different meaning than the explicit type syntax. In these cases, the explicit type syntax is still permitted:
425+
426+
```swift
415427
// WRONG: fails with "error: type 'String?' has no member 'foo'"
428+
// if `earth` is defined in an extension on `String` rather than `Optional<String>`.
416429
let planetName = String?.earth
430+
431+
// RIGHT
432+
let planetName: String? = .earth
417433
```
418-
434+
419435
```swift
420436
struct SaturnOutline: ShapeStyle { ... }
421-
437+
422438
extension ShapeStyle where Self == SaturnOutline {
423439
static var saturnOutline: SaturnOutline {
424440
SaturnOutline()
425441
}
426442
}
427-
443+
444+
// WRONG: fails with "error: static member 'saturnOutline' cannot be used on protocol metatype '(any ShapeStyle).Type'"
445+
let myShape2 = (any ShapeStyle).myShape
446+
428447
// RIGHT: If the property's type is an existential / protocol type, moving the type
429448
// to the right-hand side will result in invalid code if the value is defined in an
430449
// extension like `extension ShapeStyle where Self == SaturnOutline`.
431450
// SwiftFormat autocorrect detects this case by checking for the existential `any` keyword.
432451
let myShape1: any ShapeStyle = .saturnOutline
433-
434-
// WRONG: fails with "error: static member 'saturnOutline' cannot be used on protocol metatype '(any ShapeStyle).Type'"
435-
let myShape2 = (any ShapeStyle).myShape
436452
```
437453

438454
</details>

0 commit comments

Comments
 (0)