You're looking for the constructor signature, also known as a "newable" type. You want the parameter to addField() to be something you call new on to get an IFIeld. That is representable like this:
addField(field: new(...args: any[])=>IField) {
// ...
new field(/* some kind of arguments */);
}
That signature will accept any constructor producing an IField, but there could be a mismatch with the arguments that constructor accepts.
If you are expecting field to be called with new and a particular number and type of arguments, you can express that too. For example, if you want field to be a no-arg constructor:
addField(field: new()=>IField) {
// ...
new field(); // no arguments
}
Then, if FieldImplementation is a class with a no-arg constructor, it will succeed:
service.addField(FieldImplementation); // okay
whereas a class that requires a constructor parameter will fail, which is good:
class NeedAString implements IField {
constructor(private myString: string) { }
};
service.addField(NeedAString); // error, NeedAString is not a no-arg constructor
// error is desirable because you don't want addField() implementation
// to call new NeedAString();
Hope that helps. Good luck!