One type per file: helpful or harmful?

I consider one type per file harmful, as well as any other similarly rigid coding rule.

Take an example I posted in a another thread:

struct  X1<T> { var x: (T) }
struct  X2<T> { var x: (T, T) }
struct  X3<T> { var x: (T, T, T) }
struct  X4<T> { var x: (T, T, T, T) }
struct  X5<T> { var x: (T, T, T, T, T) }
struct  X6<T> { var x: (T, T, T, T, T, T) }
struct  X7<T> { var x: (T, T, T, T, T, T, T) }
struct  X8<T> { var x: (T, T, T, T, T, T, T, T) }
struct  X9<T> { var x: (T, T, T, T, T, T, T, T, T) }
struct X10<T> { var x: (T, T, T, T, T, T, T, T, T, T) }

typealias   X20<T> =   X2<X10<T>>
typealias   X30<T> =   X3<X10<T>>
typealias   X40<T> =   X4<X10<T>>
typealias   X50<T> =   X5<X10<T>>
typealias   X60<T> =   X6<X10<T>>
typealias   X70<T> =   X7<X10<T>>
typealias   X80<T> =   X8<X10<T>>
typealias   X90<T> =   X9<X10<T>>
typealias  X100<T> =  X10<X10<T>>
typealias  X200<T> =  X2<X100<T>>
typealias  X300<T> =  X3<X100<T>>
typealias  X400<T> =  X4<X100<T>>
typealias  X500<T> =  X5<X100<T>>
typealias  X600<T> =  X6<X100<T>>
typealias  X700<T> =  X7<X100<T>>
typealias  X800<T> =  X8<X100<T>>
typealias  X900<T> =  X9<X100<T>>
typealias X1000<T> = X10<X100<T>>

If to take the one-type-per-file rule literally that would cost 28 files! And add extra ~200 lines of code if you use the standard attribution header in each file:

//  FileName.swift
//  ProjectName
//  Created by Author on XX/XX/XXXX.

IMHO that's the definition of counterproductive.