1

How I can remove hardcoded string literals from isValidTaskID function and refer to Config keys instead?

type Config = {
  markupPreprocessing?: MarkupPreprocessingSettings;
  stylesPreprocessing?: StylesPreprocessingSettings;
};

type TasksIDs = keyof ProjectBuilderRawValidConfigFromFile;

fuction isValidTaskID(taskID: string): void {
  return taskID === "markupPreprocessing" || taskID === "stylesPreprocessing";
}

// I still need the TasksIDs tuple!
type TasksAndEntryPontsSelection: Record<TasksIDs, Array<string>>;
3
  • I'd suggest that you probably don't need isValidTaskID at all. Where are you using this function? You could instead adjust those usages such that they cause the TS compiler to type check against keyof Config. Commented Sep 3, 2020 at 1:56
  • Thank you for the comment. Well, maybe I don't need this function, but I need to validate taksID which will be inputted from console. It means, TypeScript compiler will not know at advance which value will be inputted. Commented Sep 3, 2020 at 2:03
  • Ah, I see. Do you have an instance of Config anywhere in your code which fully specifies all possible properties? If you do, you could always do an alternative dynamic check: function isValidTaskID(taskID: string) { return Object.keys(instance).some(key => taskID === key) }. Otherwise, I don't think you can escape having to do those explicit checks. Config isn't compiled into any code, it's only used for type-checking. Commented Sep 3, 2020 at 2:10

1 Answer 1

1

You can't. Since typescript is just a static linter, type definitions will be erased at runtime including all the keys in your Config type. If you want to use it make a javascript object so it can exist at runtime

type TasksIDs = keyof ProjectBuilderRawValidConfigFromFile;
const allConfigKeys: TasksIDs[] = ['markupPreprocessing', 'stylesPreprocessing']

type MarkupPreprocessingSettings = {};
type StylesPreprocessingSettings = {};
type ProjectBuilderRawValidConfigFromFile = {
    markupPreprocessing: unknown,
    stylesPreprocessing: unknown,
};

type Config = {
  markupPreprocessing?: MarkupPreprocessingSettings;
  stylesPreprocessing?: StylesPreprocessingSettings;
};

function isValidTaskID(taskID: string) {
    return allConfigKeys.includes(taskID as any);
}

console.log(isValidTaskID('a')) // false
console.log(isValidTaskID('markupPreprocessing')) // true
console.log(isValidTaskID('stylesPreprocessing')) // true

// I still need the TasksIDs tuple!
type TasksAndEntryPontsSelection = Record<TasksIDs, Array<string>>;
Sign up to request clarification or add additional context in comments.

3 Comments

I assume indexOf() is faster than includes() because it doesn't involve regex. But yes, includes() is easier to read
You assume wrong, there's no regex involved... simple identity comparison.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.