# Generics type constraints for beginners

**URL:** <https://forums.swift.org/t/generics-type-constraints-for-beginners/84572>\
**Category:** Using Swift\
**Tags:** generics\
**Created:** [February 4, 2026, 10:43pm UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572 "2026-02-04T22:43:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![belakiss](https://avatars.discourse-cdn.com/v4/letter/b/9dc877/32.png) [@belakiss](https://forums.swift.org/u/belakiss)\
**Post date:** [February 4, 2026, 10:43pm UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572/1 "2026-02-04T22:43:52Z")

</div>

Noob-ish question. Say I have a generic datatype defined like so:

```swift
struct ChartDataset<XT,YT>: Identifiable {
    var data: [ChartDatum<XT,YT>]
}

```

and I would like to constrain it to Date and Double (for use as ChartDataset\<Date,Double\> and ChartDataset\<Double,Double\>. I can't add that constraint because Date and Double are structs and I would need them to be Protocols or Classes.

Why am I trying to add constraints? I'm trying to add some fields to track min/max based on the types of XT, YT in the dataset, e.g.

```swift
    var minX:XT
    var maxX:XT
    var minY:YT
    var maxY:YT

```

but then how do I initialize them? Would I need to add a common protocol that has a min/max defined and them define the dataset using that protocol, e.g.

```swift
protocol Bounded ...
extension Double: Bounded ...
struct ChartDataset<XT:Bounded,YT:Bounded>: Identifiable {
var minX:XT = XT.minimum

```

or is there a more elegant way to accomplish this?

TIA.

---

<div class="post-metadata">

**Author:** ![deccy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/deccy/32/44988_2.png) [@deccy](https://forums.swift.org/u/deccy)\
**Post date:** [February 5, 2026, 12:55am UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572/2 "2026-02-05T00:55:07Z")

</div>

Generics are constrained by protocol conformance, and value types like structs fully participate in that. Do you need the true lower and upper-bounds of `Bounded`? For something like a chart, I would think you want `minX` to be the smallest value in `data`, not the least/greatest bound. And if so, what is considered a “min” date vs. a “min” double? For getting the min of `data` , you can use a computed property:

```swift
struct ChartDatum<XType: Comparable, YType: Comparable> {
  let x: XType
  let y: YType
}

struct ChartDataset<XType: Comparable, YType: Comparable>: Identifiable {
  var id: ObjectIdentifier
  
  var data: [ChartDatum<XType, YType>]
  
  var minX: XType? {
    data.map(\.x).min()
  }
}

```

Since you need a `min/max`, `XT/YT` need to be `Comparable` to support them (which Date and Double are). There are other ways to do a min on data as well. `minX` is optional because the array could be empty. This works as `data` conforms to `Sequence`, and `.min()` the map result is of `Comparable` elements.

---

<div class="post-metadata">

**Author:** ![belakiss](https://avatars.discourse-cdn.com/v4/letter/b/9dc877/32.png) [@belakiss](https://forums.swift.org/u/belakiss)\
**Post date:** [February 5, 2026, 8:05am UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572/3 "2026-02-05T08:05:25Z")

</div>

> [@deccy](#):
>
> For something like a chart, I would think you want `minX` to be the smallest value in `data`, not the least/greatest bound.

I initialize minX to either Date.distantFuture or Double.greatestFiniteMagnitude (depending on type) so that there doesn't need to be any special casing needed for Swift.min() when the first value is added (minX = Swift.min(minX, newX).

> [@deccy](#):
>
> And if so, what is considered a “min” date vs. a “min” double?

A "min" date would be the oldest date and a "min" double would be the smallest value.

> [@deccy](#):
>
> For getting the min of `data` , you can use a computed property

I considered using a computed property for minX, etc but I've avoided it because I've run into SwiftUI triggering unnecessary recalculation (possibly my fault) when displaying computed properties.

---

<div class="post-metadata">

**Author:** ![deccy](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/deccy/32/44988_2.png) [@deccy](https://forums.swift.org/u/deccy)\
**Post date:** [February 5, 2026, 3:15pm UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572/4 "2026-02-05T15:15:07Z")

</div>

Branch penalties aren’t too bad, and then you get readability without room for error. Smaller/larger values than the sentinel technically do exist. Since this is SwiftUI, do you need the sentinel value so that there is _something_ to render?

To avoid the View constantly calculating the `data.map(\.x).min()`, maybe something like:

```swift
private(set) var minX: XType?
mutating func append(_ datum: ChartDatum<XType, YType>) {
  minX = minX.map { min($0, datum.x) } ?? datum.x
}

```

You’re right there is no .smallest for a generic type you could use to initialize it with, but then you’re pushing UI concerns/updates into the type system.

At the View level, we know that `ChartSet`is bound to some `XT, YT`, so you’re safe to use the sentinel _there_ if you really want it:

```swift
VStack {
  if let minX = model.minX, let maxX = model.maxX {
    // draw
  } else {
    // draw a blank grid
  }

  // alternatively, since we know model is of <Date, YT>
  let minX = model.minX ?? .distantPast
  // do thing
}

```

This keeps the domain cleanly separated from view-level policy.

---

<div class="post-metadata">

**Author:** ![Gero](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gero/32/23571_2.png) [@Gero](https://forums.swift.org/u/Gero)\
**Post date:** [February 6, 2026, 10:24am UTC](https://forums.swift.org/t/generics-type-constraints-for-beginners/84572/5 "2026-02-06T10:24:41Z")

</div>

Referring back to part of the original question:

In scenarios like this, where you have two (or more) concrete types in mind you want to write generic code for the answer is generally: Yes, defining a protocol that describes their common (in your context) behavior, using it as generic constraint, and then conforming them to the protocol is the way to go. Furthermore, I'd claim that this is _very_ elegant, as it makes things extendable in the future (adding more conforming types) and also very descriptive. The protocol should have a speaking name, then it perfectly describes what it actually is you "see" in the conforming types.

The only thing you need to concern yourself with usually whether there already _is_ a protocol that nicely covers your requirement, like `Comparable`, or `Sequence`, or another one. This depends on your actual domain logic.

In this concrete case, as @deccy correctly pointed out, there also might be easier and/or more practical ways to achieve your goal.

In general though, I'd say if you define _your_ application domain's logic, expressing this with protocols and then "slotting" in existing types into that is a good design. There's a point to be made that a `Chart` makes something on `Chartable` things (I am not serious with this name, ofc) and that what makes a thing `Chartable` (or `Charitable`? 😆) could, among other things, be having specific minimum or maximum aspects.  
I like these kinds of apps that describe their domain with protocols, especially if I already know a bit of their domain.
