Which language is used to construct a type system?
OCaml and Scala are popular choices for types systems, but they are by no means the only languages you can write a compiler, interpreter, typechecker, or type system in.
Type-checking involves traversing syntax trees representing terms and types. Languages with some form of algebraic data type make this easy, since these traversals can be defined using pattern-matching . In an object oriented language, these traversals have to be done using a Vistor pattern, which ends up using much more boilerplate. Languages like Haskell can use techniques like monads or  datatype-generic programming to abstract away even more of the boilerplate of these traversals.
Also, functional programming languages tend to be closer to the lambda calculus and the other formalizations of programming languages. Since programming language researchers are often the ones developing both these formalizations and the implementations, so it makes sense that they'll be more comfortable in languages like these.
It's worth mentioning that a some work has been put into developing other ways to declaratively specify type systems for languages. For example:

Turnstile is a Racket DSL that lets you develop type systems in a form that looks a lot like formal inference rules.
Spoofax is a toolkit for writing programming languages, that can generate a typechecker with IDE integration from a specification.


A related question, is a type system for a language always written in the native language itself?

Certainly not! It's popular for writers to implement a language in the language  itself, (often called &quot;self hosting&quot;). If you're writing a programming language, then there's a good chance that it's  been designed to solve problems that whoever was writing the language had. So whoever is designing the language probably finds it a pleasant language to use.
But for performance reasons, often languages are implemented lower-level languages like C or Rust. This is particularly important for interpreted languages: if you write your interpreted language in another interpreted language, then interpreting code involves running your interpreter in yet another interpreter, which is a lot of indirection that hurts performance.