Only if you're using a language with an insufficiently strong type system (e.g. Java, C#)
in typescript:
type UnverifiedEmail = { address: string, verified; false }
type VerifiedEmail = { address: string, verified; true }
...
type Email = UnverifiedEmail | VerifiedEmail | FooBarBazEmail
const sendToEmail = (email: Email): Promise<void> = ...
in Haskell: class SendTo t where
sendTo :: t -> IO ()
newtype Email = Email string
instance SendTo Email where
sendTo (Email address) = ...
newtype VerifiedEmail = VerifiedEmail Email deriving (SendTo)
newtype FooBarBazEmail = FooBarBazEmail Email deriving (SendTo)
> I.e., due to a bug, a value of type VerifiedEmail could be created for an email address that is not really verified. Then, your static checks for VerifiedEmail don't help you at all.Of course they do - they tell you that the bug is in the verification code, and not in any of the thousands of lines of business logic separating it from the place where the error was found.