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.