struct Calc[S] { mut: typ S } struct TypeA {} struct TypeB {} fn (mut c Calc[S]) next[T](input T) f64 { $if S is TypeA || S is TypeB { return c.typ.next(input) } $else { return 99.0 } } fn (mut t TypeA) next[T](_input T) f64 { return 10 } fn (mut t TypeB) next[T](_input T) f64 { return 11 } @[markused] fn new[S]() Calc[S] { $if S is TypeA { return Calc[TypeA]{ typ: TypeA{} } } $else $if S is TypeB { return Calc[TypeB]{ typ: TypeB{} } } $else { panic('unknown type ${S.name}') } } fn main() { { mut c := Calc[TypeA]{ typ: TypeA{} } assert c.next(100) == 10.0 } { mut c := Calc[TypeB]{ typ: TypeB{} } assert c.next(100) == 11.0 } println('OK!!') }