Dear Benjamin,
I'm not sure I quite get your problem. My guess: you want a type-level guarantee that `turnOff'` function will only be applied to the terms of type `State True`, and so, you expect a compile-time error from `turnOff' off`. Am I get it right?
In your solution you seem to over engineer the solution. You try to relate type-level informaton (the value of of the type parameter `s` of `State`) to the term-level one (the value of the field stored in the `State` datatype). I think you'd better read how this task is solved with the technique known as singletons (
https://cs.brynmawr.edu/~rae/papers/2012/singletons/paper.pdf).
But I bet you don't need to solve that task to just address the problem at hand, if I understand the problem correctly. Please, tell me if the simpler solution below suits you: it doesn't use term-level (field of State) information at all.
{-# LANGUAGE DataKinds, TypeFamilies #-}
data State (s :: Bool) = State deriving Show
off :: State False
off = State
type family TurnOff s where
TurnOff True = False
turnOff :: State True -> State False
turnOff State = State
bad = turnOff off -- <-- error: Couldn't match type ‘'False’ with ‘'True’
main = print bad
--
Best, Artem