It's helpful in cases like these to study the AST structure of your code and refer to it as you build out your solution. You can analyze the AST using TypeScript AST Viewer.
Here is what your code looks like
You can see here that your MethodDeclaration has a typeParameters property, which is an array of TypeParameter. It also has parameters, which is an array of Parameter.
What you're looking to do is replace any TypeReference that occurs in any descendant of nodes in parameters which points to O with the corresponding TypeParameter O's constraint property.
There are a couple of routes you can take for this. The easiest and most widely documented approach is to use a transformer.
Example Code
The following example will apply itself to all methods. It looks for TypeReference nodes anywhere in the parameters NodeArray and checks if it's a reference to one of the method's TypeParameters. If it is, it will replace that reference with its constraint.
This is a bit broader than the your question, but I assumed your actual application may be closer to this. If not, you should be able to easily modify it to target specific methods or parameter names.
Hopefully this will help point you in the right direction
Try the code on StackBlitz: https://stackblitz.com/edit/typescript-transformer-example?file=index.ts
import * as ts from 'typescript'
import { Node, SourceFile } from 'typescript'
/* ****************************************************************************************************************** *
* Code to transform
* ****************************************************************************************************************** */
const cls = `
class Sample {
sn<O extends string>(input:{ one: O, twO : {k : O} ,three:O[] }) {
}
}
`;
/* ****************************************************************************************************************** *
* Transformer
* ****************************************************************************************************************** */
const transformer = (ctx: ts.TransformationContext) => (sourceFile: SourceFile): SourceFile => {
function paramVisitor(baseMethod: ts.MethodDeclaration) {
return (node: Node): Node => {
if (ts.isTypeReferenceNode(node)) {
const typeParam = baseMethod.typeParameters.find(t => t.name.escapedText === (node.typeName as ts.Identifier).escapedText);
if (typeParam) return typeParam.constraint;
}
return ts.visitEachChild(node, paramVisitor(baseMethod), ctx);
};
}
const visit = (node: Node): Node => {
if (ts.isMethodDeclaration(node))
return ts.updateMethod(
node,
node.decorators,
node.modifiers,
node.asteriskToken,
node.name,
node.questionToken,
node.typeParameters,
ts.visitNodes(node.parameters, paramVisitor(node)),
node.type,
node.body
);
return ts.visitEachChild(node, visit, ctx);
};
return ts.visitNode(sourceFile, visit);
};
/* ****************************************************************************************************************** *
* Demonstration
* ****************************************************************************************************************** */
const s = ts.createSourceFile('example.ts', cls, ts.ScriptTarget.ES5);
const { transformed } = ts.transform(s, [ transformer ]);
console.log(ts.createPrinter().printFile(transformed.find(f => f.fileName === 'example.ts')));
Recommended reading:
How to Write a TypeScript Transform (Plugin)
Creating a TypeScript Transformer
Recommended tools:
ts-query - For a more surgical approach
ts-morph - Can help make compiler API work easier.
ts-patch - If you need to apply transformers during tsc compilation
PS
In the future, add the tag typescript-compiler-api to your posts. These types of questions have a much better chance of being answered with that tag.